From 88dbcf2d15682f88a9880246b916302382a8cf0a Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 09:24:53 -0800 Subject: [PATCH 01/14] add missing changes from upstream commit d323a0e --- CHANGELOG.md | 2 ++ src/include/shape_h.js | 1 - src/shape_c.js | 34 ++++++++++++++++------------------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 730b793..c8f52b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next - Unreleased +* `b2Shape_RayCast(b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translation)` -> `b2Shape_RayCast(b2ShapeId shapeId, b2RayCastInput* input)` +* remove `b2GetOwnerTransform` * `b2Body_GetInertiaTensor` -> `b2Body_GetRotationalInertia` * `b2DistanceJoint_GetHertz` -> `b2DistanceJoint_GetSpringHertz` * `b2DistanceJoint_GetDampingRatio` -> `b2DistanceJoint_GetSpringDampingRatio diff --git a/src/include/shape_h.js b/src/include/shape_h.js index dd0bc6f..c360085 100644 --- a/src/include/shape_h.js +++ b/src/include/shape_h.js @@ -93,7 +93,6 @@ export { b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape, - b2GetOwnerTransform, b2Shape_AreContactEventsEnabled, b2Shape_AreHitEventsEnabled, b2Shape_ArePreSolveEventsEnabled, diff --git a/src/shape_c.js b/src/shape_c.js index 750f266..3b0499c 100644 --- a/src/shape_c.js +++ b/src/shape_c.js @@ -68,10 +68,6 @@ function b2GetShape(world, shapeId) return shape; } -export function b2GetOwnerTransform(world, shape) -{ - return b2GetBodyTransform(world, shape.bodyId); -} function b2GetChainShape(world, chainId) { @@ -1019,7 +1015,7 @@ export function b2Shape_TestPoint(shapeId, point) const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); + const transform = b2GetBodyTransform(world, shape.bodyId); const localPoint = b2InvTransformPoint(transform, point); switch (shape.type) @@ -1038,14 +1034,14 @@ export function b2Shape_TestPoint(shapeId, point) } } + /** * @function b2Shape_RayCast * @description * Performs a ray cast against a shape in world space, transforming the input/output * between local and world coordinates. * @param {b2ShapeId} shapeId - The identifier for the shape to test - * @param {b2Vec2} origin - The starting point of the ray in world coordinates - * @param {b2Vec2} translation - The direction and length of the ray in world coordinates + * @param {b2RayCastInput} input - The ray to cast, in world coordinates * @returns {b2CastOutput} The ray cast results containing: * - hit: boolean indicating if the ray intersects the shape * - point: intersection point in world coordinates (if hit is true) @@ -1053,45 +1049,46 @@ export function b2Shape_TestPoint(shapeId, point) * - fraction: fraction of translation where intersection occurs (if hit is true) * @throws {Error} Throws assertion error if shape type is invalid */ -export function b2Shape_RayCast(shapeId, origin, translation) +export function b2Shape_RayCast(shapeId, input) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); + const transform = b2GetBodyTransform(world, shape.bodyId); // input in local coordinates - const input = new b2RayCastInput(); - input.maxFraction = 1.0; - input.origin = b2InvTransformPoint(transform, origin); - input.translation = b2InvRotateVector(transform.q, translation); + const localInput = new b2RayCastInput(); + localInput.origin = b2InvTransformPoint(transform, input.origin); + localInput.translation = b2InvRotateVector(transform.q, input.translation); + localInput.maxFraction = input.maxFraction; + let output = new b2CastOutput(rayNormal, rayPoint); switch (shape.type) { case b2ShapeType.b2_capsuleShape: - output = b2RayCastCapsule(input, shape.capsule); + output = b2RayCastCapsule(localInput, shape.capsule); break; case b2ShapeType.b2_circleShape: - output = b2RayCastCircle(input, shape.circle); + output = b2RayCastCircle(localInput, shape.circle); break; case b2ShapeType.b2_segmentShape: - output = b2RayCastSegment(input, shape.segment, false); + output = b2RayCastSegment(localInput, shape.segment, false); break; case b2ShapeType.b2_polygonShape: - output = b2RayCastPolygon(input, shape.polygon); + output = b2RayCastPolygon(localInput, shape.polygon); break; case b2ShapeType.b2_chainSegmentShape: - output = b2RayCastSegment(input, shape.chainSegment.segment, true); + output = b2RayCastSegment(localInput, shape.chainSegment.segment, true); break; @@ -1111,6 +1108,7 @@ export function b2Shape_RayCast(shapeId, origin, translation) return output; } + /** * @function b2Shape_SetDensity * @summary Sets the density of a shape and optionally updates the parent body's mass. From 9e3b57c7df26d59a2c462b82783b29dce6c784fc Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 09:55:29 -0800 Subject: [PATCH 02/14] add missing changes from upstream commit c69eee4 --- CHANGELOG.md | 8 +++++ src/debug_draw.js | 1 - src/include/types_h.js | 1 - src/include/world_h.js | 3 +- src/world_c.js | 67 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8f52b1..3095c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Next - Unreleased +* add `b2World_IsSleepingEnabled` +* add `b2World_IsContinuousEnabled` +* add `b2World_GetRestitutionThreshold` +* add `b2World_GetHitEventThreshold` +* add `b2World_IsWarmStartingEnabled` +* remove `b2DebugDraw.DrawCapsule` +* + * `b2Shape_RayCast(b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translation)` -> `b2Shape_RayCast(b2ShapeId shapeId, b2RayCastInput* input)` * remove `b2GetOwnerTransform` * `b2Body_GetInertiaTensor` -> `b2Body_GetRotationalInertia` diff --git a/src/debug_draw.js b/src/debug_draw.js index ff6a458..6fdf208 100644 --- a/src/debug_draw.js +++ b/src/debug_draw.js @@ -78,7 +78,6 @@ export function CreateDebugDraw(canvas, ctx, scale = 20.0) const draw = new b2DebugDraw(); if (disableDrawing) { - draw.DrawCapsule = () => { return; } draw.DrawCircle = () => { return; } draw.DrawPoint = () => { return; } draw.DrawPolygon = () => { return; } diff --git a/src/include/types_h.js b/src/include/types_h.js index 3b786c9..96c428e 100644 --- a/src/include/types_h.js +++ b/src/include/types_h.js @@ -880,7 +880,6 @@ export class b2DebugDraw this.DrawCircle = null; this.DrawImageCircle = null; this.DrawSolidCircle = null; - this.DrawCapsule = null; this.DrawImageCapsule = null; this.DrawSolidCapsule = null; this.DrawSegment = null; diff --git a/src/include/world_h.js b/src/include/world_h.js index fde5c76..1f0d72b 100644 --- a/src/include/world_h.js +++ b/src/include/world_h.js @@ -20,7 +20,8 @@ export { b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback, b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold, b2World_IsValid, b2Joint_IsValid, - b2World_EnableSleeping, b2World_EnableContinuous, b2World_EnableWarmStarting, + b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold, + b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled, b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts, b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid, } from '../world_c.js'; diff --git a/src/world_c.js b/src/world_c.js index 91111be..991545b 100644 --- a/src/world_c.js +++ b/src/world_c.js @@ -2082,6 +2082,73 @@ export function b2World_EnableSleeping(worldId, flag) } } + + +/** + * @function b2World_IsSleepingEnabled + * @summary Is body sleeping enabled? + * @param {b2WorldId} worldId - The identifier of the Box2D world. + * @returns {boolean} True if sleeping is enabled for the world, false otherwise. + */ +export function b2World_IsSleepingEnabled(worldId) +{ + const world = b2GetWorldFromId(worldId); + return world.enableSleep; +} + + +/** + * @function b2World_IsContinuousEnabled + * @summary Is continuous collision enabled? + * @param {b2WorldId} worldId - The identifier of the Box2D world. + * @returns {boolean} True if continuous collision is enabled for the world, false otherwise. + */ +export function b2World_IsContinuousEnabled(worldId) +{ + const world = b2GetWorldFromId(worldId); + return world.enableContinuous; +} + + +/** + * @function b2World_GetRestitutionThreshold + * @summary Get the the restitution speed threshold. Typically in meters per second. + * @param {b2WorldId} worldId - The identifier of the Box2D world. + * @returns {number} float + */ +export function b2World_GetRestitutionThreshold(worldId) +{ + const world = b2GetWorldFromId(worldId); + return world.restitutionThreshold; +} + + +/** + * @function b2World_GetHitEventThreshold + * @summary Get the the hit event speed threshold. Typically in meters per second. + * @param {b2WorldId} worldId - The identifier of the Box2D world. + * @returns {number} float + */ +export function b2World_GetHitEventThreshold(worldId) +{ + const world = b2GetWorldFromId(worldId); + return world.hitEventThreshold; +} + + +/** + * @function b2World_IsWarmStartingEnabled + * @summary Is constraint warm starting enabled? + * @param {b2WorldId} worldId - The identifier of the Box2D world. + * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise. + */ +export function b2World_IsWarmStartingEnabled(worldId) +{ + const world = b2GetWorldFromId(worldId); + return world.enableWarmStarting; +} + + /** * @function b2World_EnableWarmStarting * @param {b2WorldId} worldId - The identifier for the Box2D world instance From 667d9b971b71fba41f30a26cce17f27df7a40d13 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 09:55:55 -0800 Subject: [PATCH 03/14] tweak CHANGELOG formatting --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3095c26..9386093 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,6 @@ * add `b2World_GetHitEventThreshold` * add `b2World_IsWarmStartingEnabled` * remove `b2DebugDraw.DrawCapsule` -* - * `b2Shape_RayCast(b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translation)` -> `b2Shape_RayCast(b2ShapeId shapeId, b2RayCastInput* input)` * remove `b2GetOwnerTransform` * `b2Body_GetInertiaTensor` -> `b2Body_GetRotationalInertia` From 13c5b33b4aa500a8a6ff2d9d3fd3136329287f10 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 17:08:20 -0800 Subject: [PATCH 04/14] pass through manifold argument and add note on static variable --- src/manifold_c.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/manifold_c.js b/src/manifold_c.js index 08c4f5a..869e8c1 100644 --- a/src/manifold_c.js +++ b/src/manifold_c.js @@ -753,6 +753,9 @@ export function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold) return; } + +// initialized here, used as a static variable to avoid allocating memory on every +// call to b2CollideSegmentAndCapsule const constCapsule = new b2Capsule(); /** @@ -773,7 +776,7 @@ export function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifol constCapsule.center2 = segmentA.point2; constCapsule.radius = 0; - return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB); + return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold); } /** From c0e653f1473bdf88f5e71a4f048d2e168a300037 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 17:11:16 -0800 Subject: [PATCH 05/14] add b2Joint_GetWorld, b2Chain_GetWorld, b2Chain_GetSegmentCount, b2Chain_GetSegments --- src/include/joint_h.js | 1 + src/include/shape_h.js | 3 +++ src/joint_c.js | 16 ++++++++++- src/shape_c.js | 60 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/include/joint_h.js b/src/include/joint_h.js index 0a4f013..1ad087b 100644 --- a/src/include/joint_h.js +++ b/src/include/joint_h.js @@ -469,6 +469,7 @@ export { b2GetJointSim, b2GetJointSimCheckType, b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints, b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, + b2Joint_GetWorld, b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB, b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected, b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef diff --git a/src/include/shape_h.js b/src/include/shape_h.js index c360085..767f711 100644 --- a/src/include/shape_h.js +++ b/src/include/shape_h.js @@ -131,6 +131,9 @@ export { b2Shape_SetSegment, b2Shape_SetUserData, b2Shape_TestPoint, + b2Chain_GetWorld, + b2Chain_GetSegmentCount, + b2Chain_GetSegments, b2Chain_SetFriction, b2Chain_SetRestitution, b2DestroyChain, diff --git a/src/joint_c.js b/src/joint_c.js index e3a3c93..262a1c6 100644 --- a/src/joint_c.js +++ b/src/joint_c.js @@ -30,7 +30,7 @@ import { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from "./in import { b2BufferMove } from "./include/broad_phase_h.js"; import { b2DestroyContact } from "./include/contact_h.js"; -import { b2JointId } from "./include/id_h.js"; +import { b2JointId, b2WorldId } from "./include/id_h.js"; /** * @namespace Joint @@ -1058,6 +1058,20 @@ export function b2DestroyJoint(jointId) b2DestroyJointInternal(world, joint, true); } + +/** + * Get the world that owns this joint + * @function b2Chain_GetSegments + * @param {b2JointId} jointId - The identifier for the joint + * @returns {b2WorldId} + */ +export function b2Joint_GetWorld(jointId) +{ + const world = b2GetWorld(jointId.world0); + return new b2WorldId(jointId.world0 + 1, world.revision); +} + + /** * Gets the type of a joint from its ID. * @function b2Joint_GetType diff --git a/src/shape_c.js b/src/shape_c.js index 3b0499c..df3bea9 100644 --- a/src/shape_c.js +++ b/src/shape_c.js @@ -939,6 +939,13 @@ export function b2Shape_GetBody(shapeId) return b2MakeBodyId(world, shape.bodyId); } +// +/** + * @function b2Shape_GetWorld + * @summary Get the world that owns this shape + * @param {b2ShapeId} shapeId - The ID of the shape to query. + * @returns {b2WorldId} The ID of the world that owns the shape. + */ export function b2Shape_GetWorld(shapeId) { const world = b2GetWorld(shapeId.world0); @@ -1771,6 +1778,59 @@ export function b2Shape_GetParentChain(shapeId) return new b2ChainId(); } + +/** + * Get the world that owns this chain shape + * @function b2Chain_GetWorld + * @param {b2ChainId} chainId - The identifier for the chain + * @returns {b2WorldId} + */ +export function b2Chain_GetWorld( b2ChainId chainId ) +{ + const world = b2GetWorld(chainId.world0); + return new b2WorldId(chainId.world0 + 1, world.revision); +} + + +/** + * Get the number of segments on this chain. + * @function b2Chain_GetSegmentCount + * @param {b2ChainId} chainId - The identifier for the chain + * @returns {number} + */ +export function b2Chain_GetSegmentCount(chainId) +{ + const world = b2GetWorldLocked(chainId.world0); + const chainShape = b2GetChainShape(world, chainId); + return chainShape.count; +} + + +/** + * Fill a user array with chain segment shape ids up to the specified capacity. + * @function b2Chain_GetSegments + * @param {b2ChainId} chainId - The identifier for the chain + * @param {b2ShapeId} segmentArray - list of segment shapes for this chain + * @param {number} capacity - + * @returns {number} The actual number of segments returned. + */ +export function b2Chain_GetSegments(chainId, segmentArray, capacity) +{ + const world = b2GetWorldLocked(chainId.world0); + const chainShape = b2GetChainShape(world, chainId); + const count = Math.min(chainShape.count, capacity); + + for (let i=0; i < count; ++i) + { + const shapeId = chainShape.shapeIndices[i]; + const shape = world.shapeArray[shapeId]; + segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision); + } + + return count; +} + + /** * Sets the friction value for all shapes in a chain. * @function b2Chain_SetFriction From be841fe4b78e2bcf99ece08210faeb3c8185d563 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 17:11:31 -0800 Subject: [PATCH 06/14] update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9386093..5b9548b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next - Unreleased +* add `b2Joint_GetWorld` +* add `b2Chain_GetWorld` +* add `b2Chain_GetSegmentCount` +* add `b2Chain_GetSegments` * add `b2World_IsSleepingEnabled` * add `b2World_IsContinuousEnabled` * add `b2World_GetRestitutionThreshold` From 82d1d9a4230cf39e9a98a238486bc851635a412e Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 17:16:03 -0800 Subject: [PATCH 07/14] fix errant type and update dist --- dist/PhaserBox2D-Debug.js | 87 +++++++++++++++++----------------- dist/PhaserBox2D-Debug.js.map | 4 +- dist/PhaserBox2D-Render.js | 85 +++++++++++++++++---------------- dist/PhaserBox2D-Render.js.map | 4 +- dist/PhaserBox2D.js | 82 +++++++++++++++++--------------- dist/PhaserBox2D.min.js | 4 +- src/shape_c.js | 2 +- 7 files changed, 137 insertions(+), 131 deletions(-) diff --git a/dist/PhaserBox2D-Debug.js b/dist/PhaserBox2D-Debug.js index 9c35c74..f0c7d5b 100644 --- a/dist/PhaserBox2D-Debug.js +++ b/dist/PhaserBox2D-Debug.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Wednesday 1 January 2025 at 15:57 + * Tuesday, 14 January 2025 at 17:14 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -459,7 +459,7 @@ function b2SetAssertFcn(assertFcn) { console.warn("b2SetAssertFcn not supported"); } function b2GetVersion() { - return new b2Version(3, 0, 0); + return new b2Version(3, 1, 0); } // src/include/core_h.js @@ -1495,7 +1495,6 @@ var b2DebugDraw = class { this.DrawCircle = null; this.DrawImageCircle = null; this.DrawSolidCircle = null; - this.DrawCapsule = null; this.DrawImageCapsule = null; this.DrawSolidCapsule = null; this.DrawSegment = null; @@ -2622,10 +2621,10 @@ function b2MakeRoundedBox(hx, hy, radius) { shape.radius = radius; return shape; } -function b2MakeOffsetBox(hx, hy, center, angle = 0) { +function b2MakeOffsetBox(hx, hy, center, rotation) { const xf2 = new b2Transform(); xf2.p = center; - xf2.q = b2MakeRot(angle); + xf2.q = rotation; const shape = new b2Polygon(); shape.count = 4; shape.vertices[0] = b2TransformPoint(xf2, new b2Vec2(-hx, -hy)); @@ -3068,9 +3067,6 @@ function b2GetShape(world, shapeId) { const shape = world.shapeArray[id]; return shape; } -function b2GetOwnerTransform(world, shape) { - return b2GetBodyTransform(world, shape.bodyId); -} function b2GetChainShape(world, chainId) { const id = chainId.index1 - 1; const chain = world.chainArray[id]; @@ -3142,7 +3138,7 @@ function b2CreateShapeInternal(world, body, transform, def, geometry, shapeType) shape.revision += 1; if (body.setIndex != b2SetType.b2_disabledSet) { const proxyType = body.type; - b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation); + b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor); } if (body.headShapeId != B2_NULL_INDEX) { const headShape = world.shapeArray[body.headShapeId]; @@ -3598,7 +3594,7 @@ function b2Shape_IsSensor(shapeId) { function b2Shape_TestPoint(shapeId, point) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); + const transform = b2GetBodyTransform(world, shape.bodyId); const localPoint = b2InvTransformPoint(transform, point); switch (shape.type) { case b2ShapeType.b2_capsuleShape: @@ -3611,30 +3607,30 @@ function b2Shape_TestPoint(shapeId, point) { return false; } } -function b2Shape_RayCast(shapeId, origin, translation) { +function b2Shape_RayCast(shapeId, input) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); - const input = new b2RayCastInput(); - input.maxFraction = 1; - input.origin = b2InvTransformPoint(transform, origin); - input.translation = b2InvRotateVector(transform.q, translation); + const transform = b2GetBodyTransform(world, shape.bodyId); + const localInput = new b2RayCastInput(); + localInput.origin = b2InvTransformPoint(transform, input.origin); + localInput.translation = b2InvRotateVector(transform.q, input.translation); + localInput.maxFraction = input.maxFraction; let output = new b2CastOutput(rayNormal3, rayPoint3); switch (shape.type) { case b2ShapeType.b2_capsuleShape: - output = b2RayCastCapsule(input, shape.capsule); + output = b2RayCastCapsule(localInput, shape.capsule); break; case b2ShapeType.b2_circleShape: - output = b2RayCastCircle(input, shape.circle); + output = b2RayCastCircle(localInput, shape.circle); break; case b2ShapeType.b2_segmentShape: - output = b2RayCastSegment(input, shape.segment, false); + output = b2RayCastSegment(localInput, shape.segment, false); break; case b2ShapeType.b2_polygonShape: - output = b2RayCastPolygon(input, shape.polygon); + output = b2RayCastPolygon(localInput, shape.polygon); break; case b2ShapeType.b2_chainSegmentShape: - output = b2RayCastSegment(input, shape.chainSegment.segment, true); + output = b2RayCastSegment(localInput, shape.chainSegment.segment, true); break; default: console.assert(false); @@ -7086,12 +7082,12 @@ function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); base.distanceJoint.dampingRatio = dampingRatio; } -function b2DistanceJoint_GetHertz(jointId) { +function b2DistanceJoint_GetSpringHertz(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.hertz; } -function b2DistanceJoint_GetDampingRatio(jointId) { +function b2DistanceJoint_GetSpringDampingRatio(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.dampingRatio; @@ -8940,7 +8936,7 @@ function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideCon const bodyIdB = bodyB.id; const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex); const jointId = b2AllocId(world.jointIdPool); - console.assert(jointId != B2_NULL_INDEX); + console.assert(jointId !== B2_NULL_INDEX); while (jointId >= world.jointArray.length) { world.jointArray.push(new b2Joint()); } @@ -9030,7 +9026,8 @@ function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideCon console.assert(jointSim.bodyIdA === bodyIdA); console.assert(jointSim.bodyIdB === bodyIdB); if (joint.setIndex > b2SetType.b2_disabledSet) { - b2LinkJoint(world, joint); + const mergeIslands = true; + b2LinkJoint(world, joint, mergeIslands); } b2ValidateSolverSets(world); return new b2JointPair(joint, jointSim); @@ -9318,7 +9315,9 @@ function b2DestroyJointInternal(world, joint, wakeBodies) { bodyB.headJointKey = edgeB.nextKey; } bodyB.jointCount -= 1; - b2UnlinkJoint(world, joint); + if (joint.islandId !== B2_NULL_INDEX) { + b2UnlinkJoint(world, joint); + } const setIndex = joint.setIndex; const localIndex = joint.localIndex; if (setIndex === b2SetType.b2_awakeSet) { @@ -10251,7 +10250,7 @@ function b2AddJointToIsland(world, islandId, joint) { joint.islandId = islandId; b2ValidateIsland(world, islandId); } -function b2LinkJoint(world, joint) { +function b2LinkJoint(world, joint, mergeIslands) { const bodyA = b2GetBody(world, joint.edges[0].bodyId); const bodyB = b2GetBody(world, joint.edges[1].bodyId); if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet) { @@ -10301,6 +10300,9 @@ function b2LinkJoint(world, joint) { } else { b2AddJointToIsland(world, islandIdB, joint); } + if (mergeIslands) { + b2MergeAwakeIslands(world); + } } function b2UnlinkJoint(world, joint) { console.assert(joint.islandId !== B2_NULL_INDEX); @@ -11407,11 +11409,11 @@ function b2Body_SetType(bodyId, type) { if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody) { continue; } - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, false); } + b2MergeAwakeIslands(world); } b2UpdateBodyMassData(world, body); - b2ValidateConnectivity(world); b2ValidateSolverSets(world); } function b2Body_SetUserData(bodyId, userData) { @@ -11430,7 +11432,7 @@ function b2Body_GetMass(bodyId) { const bodySim = b2GetBodySim(world, body); return bodySim.mass; } -function b2Body_GetInertiaTensor(bodyId) { +function b2Body_GetRotationalInertia(bodyId) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); const bodySim = b2GetBodySim(world, body); @@ -11567,10 +11569,10 @@ function b2Body_IsSleepEnabled(bodyId) { const body = b2GetBodyFullId(world, bodyId); return body.enableSleep; } -function b2Body_SetSleepThreshold(bodyId, sleepVelocity) { +function b2Body_SetSleepThreshold(bodyId, sleepThreshold) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); - body.sleepThreshold = sleepVelocity; + body.sleepThreshold = sleepThreshold; } function b2Body_GetSleepThreshold(bodyId) { const world = b2GetWorld(bodyId.world0); @@ -11653,6 +11655,7 @@ function b2Body_Enable(bodyId) { if (setId !== b2SetType.b2_staticSet) { b2CreateIslandForBody(world, setId, body); } + const mergeIslands = false; let jointKey = body.headJointKey; while (jointKey !== B2_NULL_INDEX) { const jointId = jointKey >> 1; @@ -11677,10 +11680,10 @@ function b2Body_Enable(bodyId) { const jointSet = world.solverSetArray[jointSetId]; b2TransferJoint(world, jointSet, disabledSet, joint); if (jointSetId !== b2SetType.b2_staticSet) { - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, mergeIslands); } } - b2ValidateConnectivity(world); + b2MergeAwakeIslands(world); b2ValidateSolverSets(world); } function b2Body_SetFixedRotation(bodyId, flag) { @@ -12128,7 +12131,8 @@ var p2 = new b2Vec2(); var q1 = new b2Vec2(); var q2 = new b2Vec2(); function b2MakeCapsule(p14, p23, radius) { - const axis = b2NormalizeChecked(b2Sub(p23, p14)); + const d = b2Sub(p23, p14); + const axis = b2Normalize(d); const normal = b2RightPerp(axis); const shape = new b2Polygon(); shape.vertices = [p14, p23]; @@ -12568,7 +12572,7 @@ function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold) { constCapsule.center1 = segmentA.point1; constCapsule.center2 = segmentA.point2; constCapsule.radius = 0; - return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB); + return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold); } function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold) { const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius); @@ -16201,7 +16205,7 @@ function CreateBoxPolygon(data) { let box; if (data.size instanceof b2Vec2) { if (data.bodyId) { - box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, 0); + box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0)); } else { box = b2MakeBox(data.size.x, data.size.y); } @@ -16627,9 +16631,6 @@ function CreateDebugDraw(canvas, ctx, scale = 20) { } const draw = new b2DebugDraw(); if (disableDrawing) { - draw.DrawCapsule = () => { - return; - }; draw.DrawCircle = () => { return; }; @@ -17465,7 +17466,6 @@ export { b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_GetGravityScale, - b2Body_GetInertiaTensor, b2Body_GetJointCount, b2Body_GetJoints, b2Body_GetLinearDamping, @@ -17477,6 +17477,7 @@ export { b2Body_GetMassData, b2Body_GetPosition, b2Body_GetRotation, + b2Body_GetRotationalInertia, b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetSleepThreshold, @@ -17586,14 +17587,14 @@ export { b2DistanceJoint_EnableMotor, b2DistanceJoint_EnableSpring, b2DistanceJoint_GetCurrentLength, - b2DistanceJoint_GetDampingRatio, - b2DistanceJoint_GetHertz, b2DistanceJoint_GetLength, b2DistanceJoint_GetMaxLength, b2DistanceJoint_GetMaxMotorForce, b2DistanceJoint_GetMinLength, b2DistanceJoint_GetMotorForce, b2DistanceJoint_GetMotorSpeed, + b2DistanceJoint_GetSpringDampingRatio, + b2DistanceJoint_GetSpringHertz, b2DistanceJoint_IsLimitEnabled, b2DistanceJoint_IsMotorEnabled, b2DistanceJoint_IsSpringEnabled, diff --git a/dist/PhaserBox2D-Debug.js.map b/dist/PhaserBox2D-Debug.js.map index b21ea78..6ca0730 100644 --- a/dist/PhaserBox2D-Debug.js.map +++ b/dist/PhaserBox2D-Debug.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 0, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawCapsule = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MakeRot,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {number} angle - The rotation angle of the box in radians\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, angle = 0)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = b2MakeRot(angle);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\nexport function b2GetOwnerTransform(world, shape)\n{\n return b2GetBodyTransform(world, shape.bodyId);\n}\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetOwnerTransform(world, shape);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2Vec2} origin - The starting point of the ray in world coordinates\n * @param {b2Vec2} translation - The direction and length of the ray in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, origin, translation)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetOwnerTransform(world, shape);\n\n // input in local coordinates\n const input = new b2RayCastInput();\n input.maxFraction = 1.0;\n input.origin = b2InvTransformPoint(transform, origin);\n input.translation = b2InvRotateVector(transform.q, translation);\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(input, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(input, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(input, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(input, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(input, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2GetOwnerTransform,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // let rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // let rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // let ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId != B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n b2LinkJoint(world, joint);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n b2UnlinkJoint(world, joint);\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint);\n }\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Gets the inertia tensor value for a specified body.\n * @function b2Body_GetInertiaTensor\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetInertiaTensor(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepVelocity - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepVelocity;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint);\n }\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetInertiaTensor, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeChecked,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const axis = b2NormalizeChecked(b2Sub(p2, p1));\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_EnableWarmStarting,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, 0);\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCapsule = () => { return; }\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetInertiaTensor,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetHertz,\n b2DistanceJoint_GetDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": ";AAmHO,SAAS,wBAAwB,GACxC;AACI,QAAM,SAAS,SAAS,CAAC;AAEzB,MAAI,SAAS,KACb;AACI,WAAO,EAAE,QAAQ,GAAG,QAAQ,IAAI,OAAO,GAAG,CAAC,EAAE;AAAA,EACjD;AAEA,QAAM,YAAY,IAAM;AAExB,SAAO,EAAE,QAAgB,QAAQ,IAAI,OAAQ,YAAY,EAAE,GAAG,YAAY,EAAE,CAAE,EAAE;AACpF;;;ACtHO,IAAM,QAAQ;AACd,IAAM,MAAM;AACZ,IAAM,SAAS,MAAM;AAErB,IAAM,cAAc;AAAA,EACvB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,2BAA2B;AAAA,EAC3B,cAAc;AAClB;AAEO,IAAM,cAAc;AAAA,EACvB,OAAO,CAAC;AACZ;AAEO,IAAM,cAAc;AAAA,EACvB,OAAO,CAAC;AACZ;AAEO,IAAM,uBAAuB;AAAA,EAChC,OAAO,CAAC;AACZ;AAYA,IAAM,SAAN,MAAM,QACN;AAAA,EACI,YAAY,IAAI,GAAG,IAAI,GACvB;AAYI,SAAK,IAAI;AACT,SAAK,IAAI;AAAA,EACb;AAAA,EAEA,KAAK,GACL;AACI,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,EAAE;AAEX,WAAO;AAAA,EACX;AAAA,EAEA,QACA;AACI,WAAO,IAAI,QAAO,KAAK,GAAG,KAAK,CAAC;AAAA,EACpC;AACJ;AAQA,IAAM,QAAN,MAAM,OACN;AAAA,EACI,YAAYA,KAAI,GAAG,IAAI,GACvB;AAYI,SAAK,IAAIA;AACT,SAAK,IAAI;AAAA,EACb;AAAA,EAEA,KAAK,GACL;AACI,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,EAAE;AAEX,WAAO;AAAA,EACX;AAAA,EAEA,QACA;AACI,WAAO,IAAI,OAAM,KAAK,GAAG,KAAK,CAAC;AAAA,EACnC;AACJ;AAQA,IAAM,cAAN,MAAM,aACN;AAAA,EACI,YAAYC,KAAI,MAAMC,KAAI,MAC1B;AACI,SAAK,IAAID;AACT,SAAK,IAAIC;AAAA,EACb;AAAA,EAEA,OAAO,WACP;AACI,WAAO,IAAI,aAAY,IAAI,OAAO,GAAG,IAAI,MAAM,CAAC;AAAA,EACpD;AAAA,EAEA,QACA;AACI,UAAMC,MAAK,IAAI,aAAY,KAAK,GAAG,KAAK,CAAC;AAEzC,WAAOA;AAAA,EACX;AAAA,EAEA,YACA;AACI,UAAMA,MAAK,IAAI,aAAY,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC;AAEzD,WAAOA;AAAA,EACX;AACJ;AAOA,IAAM,UAAN,MAAM,SACN;AAAA,EACI,YAAY,KAAK,IAAI,OAAO,GAAG,KAAK,IAAI,OAAO,GAC/C;AACI,SAAK,KAAK;AACV,SAAK,KAAK;AAAA,EACd;AAAA,EAEA,QACA;AACI,WAAO,IAAI,SAAQ,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAAA,EACvD;AACJ;AAQA,IAAM,SAAN,MACA;AAAA,EACI,YAAY,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GACzD;AACI,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AACJ;AAiBA,SAAS,WAAW,GAAG,GACvB;AACI,SAAO,IAAI,IAAI,IAAI;AACvB;AASA,SAAS,WAAW,GAAG,GACvB;AACI,SAAO,IAAI,IAAI,IAAI;AACvB;AAWA,SAAS,WAAW,GACpB;AACI,SAAO,IAAI,IAAI,CAAC,IAAI;AACxB;AAYA,SAAS,aAAa,GAAG,OAAO,OAChC;AACI,SAAO,IAAI,QAAQ,QAAS,IAAI,QAAQ,QAAQ;AACpD;AAYA,SAAS,SAAS,GAAG,GACrB;AACI,SAAO,IAAI,IAAI,IAAI;AACvB;AASA,SAAS,SAAS,GAAG,GACrB;AACI,SAAO,IAAI,IAAI,IAAI;AACvB;AAUA,SAAS,SAAS,GAClB;AACI,SAAO,IAAI,IAAI,CAAC,IAAI;AACxB;AAYA,SAAS,WAAW,GAAG,OAAO,OAC9B;AACI,SAAO,IAAI,QAAQ,QAAS,IAAI,QAAQ,QAAQ;AACpD;AAYA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/B;AAYA,SAAS,QAAQ,GAAG,GACpB;AACI,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/B;AAYA,SAAS,UAAU,GAAG,GACtB;AACI,SAAO,IAAI,OAAO,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;AACvC;AAYA,SAAS,UAAU,GAAG,GACtB;AACI,SAAO,IAAI,OAAO,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AACvC;AAaA,SAAS,WAAW,GACpB;AACI,SAAO,IAAI,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;AAC/B;AAWA,SAAS,YAAY,GACrB;AACI,SAAO,IAAI,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;AAC/B;AAYA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,IAAI,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1C;AAYA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,IAAI,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1C;AAUA,SAAS,MAAM,GACf;AACI,SAAO,IAAI,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAChC;AAcA,SAAS,OAAO,GAAG,GAAG,GACtB;AACI,SAAO,IAAI,QAAQ,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;AACtE;AAYA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,IAAI,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1C;AAYA,SAAS,QAAQ,GAAG,GACpB;AACI,SAAO,IAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AACtC;AAUA,SAAS,SAAS,GAAG,GAAG,GACxB;AACI,SAAO,IAAI,OAAO,EAAE,IAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;AAClD;AAEA,SAAS,YAAY,GAAG,GAAG,GAAG,KAC9B;AACI,MAAI,IAAI,EAAE,IAAI,IAAI,EAAE;AACpB,MAAI,IAAI,EAAE,IAAI,IAAI,EAAE;AACxB;AAUA,SAAS,SAAS,GAAG,GAAG,GACxB;AACI,SAAO,IAAI,OAAO,EAAE,IAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;AAClD;AAEA,SAAS,SAAS,MAAM,MAAM,KAC9B;AACI,QAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,QAAM,OAAO,KAAK,IAAI,KAAK;AAE3B,SAAO,OAAO,IAAI,IAAI,OAAO,IAAI;AACrC;AAQA,SAAS,MAAM,GACf;AACI,SAAO,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;AAClD;AASA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,IAAI,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;AAC5D;AAaA,SAAS,MAAM,GAAG,GAClB;AACI,SAAO,IAAI,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;AAC5D;AAcA,SAAS,QAAQ,GAAG,GAAG,GACvB;AACI,SAAO,IAAI;AAAA,IACP,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAAA,IAC1B,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAAA,EAC9B;AACJ;AAUA,SAAS,SAAS,GAClB;AACI,SAAO,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC1C;AAEA,SAAS,WAAW,GAAG,GACvB;AACI,SAAO,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC;AAClC;AAWA,SAAS,gBAAgB,GACzB;AACI,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/B;AAWA,SAAS,WAAW,GAAG,GACvB;AACI,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AAEnB,SAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACtC;AAYA,SAAS,kBAAkB,GAAG,GAC9B;AACI,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AAEnB,SAAO,KAAK,KAAK,KAAK;AAC1B;AAWA,SAAS,UAAU,OACnB;AACI,SAAO,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK,CAAC;AACrD;AAWA,SAAS,eAAeD,IACxB;AACI,QAAM,MAAM,KAAK,KAAKA,GAAE,IAAIA,GAAE,IAAIA,GAAE,IAAIA,GAAE,CAAC;AAC3C,QAAM,SAAS,MAAM,IAAI,IAAI,MAAM;AAEnC,SAAO,IAAI,MAAMA,GAAE,IAAI,QAAQA,GAAE,IAAI,MAAM;AAC/C;AAEA,SAAS,YAAYF,IAAG,GACxB;AACI,QAAM,MAAM,KAAK,KAAK,IAAI,IAAIA,KAAIA,EAAC;AACnC,QAAM,SAAS,MAAM,IAAI,IAAI,MAAM;AAEnC,SAAO;AACX;AAWA,SAAS,eAAeE,IACxB;AACI,QAAM,KAAKA,GAAE,IAAIA,GAAE,IAAIA,GAAE,IAAIA,GAAE;AAE/B,SAAO,IAAI,OAAS,MAAM,KAAK,IAAI;AACvC;AAaA,SAAS,QAAQE,KAAIC,KAAI,GACzB;AACI,QAAM,MAAM,IAAI;AAChB,QAAMH,KAAI,IAAI;AAAA,IACV,MAAME,IAAG,IAAI,IAAIC,IAAG;AAAA,IACpB,MAAMD,IAAG,IAAI,IAAIC,IAAG;AAAA,EACxB;AAEA,SAAO,eAAeH,EAAC;AAC3B;AAaA,SAAS,oBAAoBE,KAAI,YACjC;AACI,QAAM,MAAOA,IAAG,IAAI,aAAaA,IAAG;AACpC,QAAM,MAAOA,IAAG,IAAI,aAAaA,IAAG;AACpC,QAAM,MAAM,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG;AAC3C,QAAM,SAAS,MAAM,IAAI,IAAI,MAAM;AAEnC,SAAO,IAAI,MAAM,MAAM,QAAQ,MAAM,MAAM;AAC/C;AAEA,SAAS,uBAAuBA,KAAI,YAAY,KAChD;AACI,QAAM,MAAOA,IAAG,IAAI,aAAaA,IAAG;AACpC,QAAM,MAAOA,IAAG,IAAI,aAAaA,IAAG;AACpC,QAAM,MAAM,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG;AAC3C,QAAM,SAAS,MAAM,IAAI,IAAI,MAAM;AACnC,MAAI,IAAI,MAAM;AACd,MAAI,IAAI,MAAM;AAClB;AAcA,SAAS,yBAAyBA,KAAIC,KAAI,OAC1C;AACI,SAAO,SAASA,IAAG,IAAID,IAAG,IAAIC,IAAG,IAAID,IAAG;AAC5C;AAWA,SAAS,eAAeF,IACxB;AACI,SAAO,KAAK,MAAMA,GAAE,GAAGA,GAAE,CAAC;AAC9B;AAWA,SAAS,eAAeA,IACxB;AACI,SAAO,IAAI,OAAOA,GAAE,GAAGA,GAAE,CAAC;AAC9B;AAWA,SAAS,eAAeA,IACxB;AACI,SAAO,IAAI,OAAO,CAACA,GAAE,GAAGA,GAAE,CAAC;AAC/B;AAcA,SAAS,SAASA,IAAG,GACrB;AACI,SAAO,IAAI;AAAA,IACPA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,IACpBA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,EACxB;AACJ;AAEA,SAAS,UAAUA,IAAG,GACtB;AACI,SAAOA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAC/B;AAEA,SAAS,UAAUA,IAAG,GACtB;AACI,SAAOA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAC/B;AAaA,SAAS,YAAYA,IAAG,GACxB;AACI,SAAO,IAAI;AAAA,IACPA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,IACpBA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,EACxB;AACJ;AAYA,SAAS,gBAAgB,GAAG,GAC5B;AACI,QAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC9B,QAAMF,KAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAE9B,SAAO,KAAK,MAAM,GAAGA,EAAC;AAC1B;AAYA,SAAS,cAAc,OACvB;AACI,MAAI,QAAQ,CAAC,OACb;AACI,WAAO,QAAQ,IAAI;AAAA,EACvB,WACS,QAAQ,OACjB;AACI,WAAO,QAAQ,IAAI;AAAA,EACvB;AAEA,SAAO;AACX;AAcA,SAAS,eAAeE,IAAG,GAC3B;AACI,SAAO,IAAI,OAAOA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE,GAAGA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE,CAAC;AAClE;AAaA,SAAS,kBAAkBA,IAAG,GAC9B;AACI,SAAO,IAAI,OAAOA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE,GAAG,CAACA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE,CAAC;AACnE;AAcA,SAAS,iBAAiB,GAAGD,IAC7B;AACI,QAAM,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAC5C,QAAM,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAE5C,SAAO,IAAI,OAAO,GAAG,CAAC;AAC1B;AAEA,SAAS,oBAAoB,GAAGA,IAAG,KACnC;AACI,QAAM,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAC5C,QAAM,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAG5C,MAAI,IAAI;AACR,MAAI,IAAI;AACZ;AAEA,SAAS,sBAAsB,GAAGA,IAAG,KACrC;AACI,MAAI,EAAE,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAC5C,MAAI,EAAE,IAAK,EAAE,EAAE,IAAIA,GAAE,IAAI,EAAE,EAAE,IAAIA,GAAE,IAAK,EAAE,EAAE;AAC5C,MAAI,EAAE,IAAI,EAAE,EAAE;AACd,MAAI,EAAE,IAAI,EAAE,EAAE;AAClB;AAaA,SAAS,oBAAoB,GAAGA,IAChC;AACI,QAAM,KAAKA,GAAE,IAAI,EAAE,EAAE;AACrB,QAAM,KAAKA,GAAE,IAAI,EAAE,EAAE;AAErB,SAAO,IAAI,OAAO,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE,IAAI,EAAE;AACvE;AAaA,SAAS,gBAAgB,GAAG,GAC5B;AACI,QAAM,IAAI,IAAI,YAAY;AAC1B,IAAE,IAAI,SAAS,EAAE,GAAG,EAAE,CAAC;AACvB,IAAE,IAAI,MAAM,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AAEzC,SAAO;AACX;AAaA,SAAS,mBAAmB,GAAG,GAC/B;AACI,QAAM,IAAI,IAAI,YAAY,IAAI,OAAO,GAAG,IAAI,MAAM,CAAC;AAInD,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE;AACpC,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE;AAIpC,QAAM,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE;AACzB,QAAM,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE;AACzB,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,IAAI;AAC/B,IAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,IAAI;AAEhC,SAAO;AACX;AAEA,SAAS,sBAAsB,GAAG,GAAG,KACrC;AACI,QAAM,IAAI;AAIV,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE;AACpC,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE;AAIpC,QAAM,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE;AACzB,QAAM,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE;AACzB,IAAE,EAAE,IAAI,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,IAAI;AAC/B,IAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,IAAI;AACpC;AAYA,SAAS,QAAQ,GAAG,GACpB;AACI,SAAO,IAAI;AAAA,IACP,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE;AAAA,IAC1B,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE;AAAA,EAC9B;AACJ;AAYA,SAAS,eAAe,GACxB;AACI,QAAM,IAAI,EAAE,GAAG,GACX,IAAI,EAAE,GAAG,GACTD,KAAI,EAAE,GAAG,GACT,IAAI,EAAE,GAAG;AACb,MAAI,MAAM,IAAI,IAAI,IAAIA;AAEtB,MAAI,QAAQ,GACZ;AACI,UAAM,IAAI;AAAA,EACd;AAEA,SAAO,IAAI;AAAA,IACP,IAAI,OAAO,MAAM,GAAG,CAAC,MAAMA,EAAC;AAAA,IAC5B,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAChC;AACJ;AAcA,SAAS,UAAU,GAAG,GACtB;AACI,QAAM,MAAM,EAAE,GAAG,GACb,MAAM,EAAE,GAAG,GACX,MAAM,EAAE,GAAG,GACX,MAAM,EAAE,GAAG;AACf,MAAI,MAAM,MAAM,MAAM,MAAM;AAE5B,MAAI,QAAQ,GACZ;AACI,UAAM,IAAI;AAAA,EACd;AAEA,SAAO,IAAI;AAAA,IACP,OAAO,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,IAC3B,OAAO,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,EAC/B;AACJ;AAaA,SAAS,gBAAgB,GAAG,GAC5B;AACI,SACI,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE;AAE3B;AAWA,SAAS,cAAc,GACvB;AACI,SAAO,IAAI;AAAA,IACP,OAAO,EAAE,cAAc,EAAE;AAAA,IACzB,OAAO,EAAE,cAAc,EAAE;AAAA,EAC7B;AACJ;AAWA,SAAS,eAAe,GACxB;AACI,SAAO,IAAI;AAAA,IACP,OAAO,EAAE,cAAc,EAAE;AAAA,IACzB,OAAO,EAAE,cAAc,EAAE;AAAA,EAC7B;AACJ;AAaA,SAAS,aAAa,GAAG,GACzB;AACI,QAAMA,KAAI,IAAI,OAAO;AACrB,EAAAA,GAAE,cAAc,KAAK,IAAI,EAAE,aAAa,EAAE,WAAW;AACrD,EAAAA,GAAE,cAAc,KAAK,IAAI,EAAE,aAAa,EAAE,WAAW;AACrD,EAAAA,GAAE,cAAc,KAAK,IAAI,EAAE,aAAa,EAAE,WAAW;AACrD,EAAAA,GAAE,cAAc,KAAK,IAAI,EAAE,aAAa,EAAE,WAAW;AAErD,SAAOA;AACX;AAWA,SAAS,UAAU,GACnB;AACI,SAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;AAClC;AAQA,SAAS,eAAe,GACxB;AACI,SAAO,KAAK,UAAU,EAAE,CAAC,KAAK,UAAU,EAAE,CAAC;AAC/C;AAaA,SAAS,cAAcE,IACvB;AACI,SAAOA,MAAK,UAAUA,GAAE,CAAC,KAAK,UAAUA,GAAE,CAAC,KAAK,eAAeA,EAAC;AACpE;AAcA,SAAS,eAAe,MACxB;AACI,MAAI,CAAC,MAAM;AAAE,WAAO;AAAA,EAAO;AAC3B,QAAM,KAAK,KAAK,cAAc,KAAK;AACnC,QAAM,KAAK,KAAK,cAAc,KAAK;AACnC,QAAM,QAAQ,MAAM,KAAK,MAAM;AAE/B,SAAO,SACH,UAAU,KAAK,WAAW,KAAK,UAAU,KAAK,WAAW,KACzD,UAAU,KAAK,WAAW,KAAK,UAAU,KAAK,WAAW;AACjE;AAaA,SAAS,YAAY,GACrB;AACI,MAAI,CAAC,GAAG;AAAE,YAAQ,OAAO,KAAK;AAAA,EAAG;AACjC,QAAM,SAAS,SAAS,CAAC;AAEzB,MAAI,SAAS,KACb;AACI,UAAM,YAAY,IAAI;AAEtB,WAAO,IAAI,OAAO,EAAE,IAAI,WAAW,EAAE,IAAI,SAAS;AAAA,EACtD;AAEA,SAAO,IAAI,OAAO,GAAG,CAAC;AAC1B;AAuBA,SAAS,mBAAmB,GAC5B;AACI,QAAM,SAAS,SAAS,CAAC;AACzB,UAAQ,OAAO,SAAS,GAAG;AAC3B,QAAM,YAAY,IAAI;AAEtB,SAAO,IAAI,OAAO,EAAE,IAAI,WAAW,EAAE,IAAI,SAAS;AACtD;;;AC/yCO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAC7C;AAEI,SAAK,QAAQ;AAGb,SAAK,QAAQ;AAGb,SAAK,WAAW;AAAA,EACpB;AACJ;;;ACdA,IAAI,yBAAyB;AAC7B,IAAM,gBAAgB;AAcf,SAAS,yBAAyB,aACzC;AAEI,2BAAyB;AAC7B;AAUO,SAAS,2BAChB;AACI,SAAO;AACX;AAYO,SAAS,eAAe,WAC/B;AACI,UAAQ,KAAK,8BAA8B;AAC/C;AASO,SAAS,eAChB;AACI,SAAO,IAAI,UAAU,GAAG,GAAG,CAAC;AAChC;;;AC/DO,IAAMI,0BAAyB;AAI/B,IAAM,UAAS,MAAWA;AAI1B,IAAM,qBAAqB;AAK3B,IAAM,gBAAgB,OAAQA;AAQ9B,IAAM,kBAAkB,OAAO,KAAK;AAGpC,IAAM,yBAAyB,IAAM;AAMrC,IAAM,gBAAgB,MAAMC;AAG5B,IAAM,iBAAiB;AAwBvB,SAAS,iBAChB;AACI,UAAQ,KAAK,8BAA8B;AAC/C;AAUO,SAAS,iBAChB;AACI,UAAQ,KAAK,8BAA8B;AAC/C;AAUO,SAAS,gBAChB;AACI,UAAQ,KAAK,6BAA6B;AAC9C;AAWO,SAAS,aAChB;AACI,UAAQ,KAAK,0BAA0B;AAC3C;AAWO,SAAS,oBAChB;AACI,UAAQ,KAAK,iCAAiC;AAClD;AAaO,SAAS,0BAA0B,OAC1C;AACI,UAAQ,KAAK,yCAAyC;AAC1D;AAWO,SAAS,oBAAoB,IACpC;AACI,UAAQ,KAAK,mCAAmC;AACpD;AAUO,SAAS,UAChB;AACI,UAAQ,KAAK,uBAAuB;AACxC;;;ACtIO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,WAAW,GAClC;AACI,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;AASO,IAAM,WAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAC7C;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;AASO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAC7C;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;AASO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAC7C;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;AASO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAC7C;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;AAoBO,SAAS,WAAW,IAC3B;AACI,SAAO,GAAG,WAAW;AACzB;AAWO,SAAS,eAAe,IAC/B;AACI,SAAO,GAAG,WAAW;AACzB;AAYO,SAAS,aAAa,KAAK,KAClC;AACI,SAAO,IAAI,WAAW,IAAI,UAAU,IAAI,WAAW,IAAI,UAAU,IAAI,aAAa,IAAI;AAC1F;;;ACnJO,IAAM,0BAA0B;AAEhC,IAAM,uBAAuB;AAW7B,IAAM,iBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AACJ;AAWO,IAAM,mBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,CAAC;AACf,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AACJ;AAWO,IAAM,eAAN,MACP;AAAA,EACI,YAAY,SAAS,MAAM,QAAQ,MACnC;AACI,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,MAAM;AAAA,EACf;AACJ;AASO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,oBAAoB;AAAA,EAC7B;AACJ;AAQO,IAAM,WAAN,MACP;AAAA,EACI,YAAY,SAAS,MAAM,SAAS,GACpC;AACI,SAAK,SAAS;AAEd,QAAI,CAAC,KAAK,QACV;AACI,WAAK,SAAS,IAAI,OAAO,GAAE,CAAC;AAAA,IAChC;AAEA,SAAK,SAAS;AAAA,EAClB;AACJ;AASO,IAAM,YAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,EAClB;AACJ;AAYO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,UACZ;AACI,QAAI,WAAW,GACf;AACI,WAAK,WAAW,IAAI,MAAM,QAAQ,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,OAAO,GAAE,CAAC,CAAC;AACpE,WAAK,UAAU,IAAI,MAAM,QAAQ,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,OAAO,GAAE,CAAC,CAAC;AAAA,IACvE,OAEA;AACI,WAAK,WAAW,CAAC;AACjB,WAAK,UAAU,CAAC;AAAA,IACpB;AAEA,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACjB;AACJ;AAQO,IAAM,YAAN,MACP;AAAA,EACI,YAAY,SAAS,MAAM,SAAS,MACpC;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAClB;AACJ;AAEO,IAAM,iBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACnB;AACJ;AASO,IAAM,SAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,CAAC;AACf,SAAK,QAAQ;AAAA,EACjB;AACJ;AAWO,IAAM,0BAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,kBAAkB;AAAA,EAC3B;AACJ;AASO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,YAAY,SAAS,CAAC,GAAG,QAAQ,MAAM,SAAS,GAChD;AACI,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,QACA;AACI,UAAM,SAAS,CAAC;AAEhB,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,IAAI,GAAG,KAC/C;AACI,aAAO,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,IAC9B;AAEA,WAAO,IAAI,iBAAgB,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,EAC9D;AACJ;AASO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,cACA;AACI,SAAK,QAAQ;AACb,SAAK,SAAS,CAAE,GAAE,GAAE,CAAE;AACtB,SAAK,SAAS,CAAE,GAAE,GAAE,CAAE;AAAA,EAE1B;AAAA,EACA,QACA;AACI,UAAM,QAAQ,IAAI,iBAAgB;AAClC,UAAM,QAAQ,KAAK;AACnB,UAAM,SAAS,CAAE,GAAG,KAAK,MAAO;AAChC,UAAM,SAAS,CAAE,GAAG,KAAK,MAAO;AAEhC,WAAO;AAAA,EACX;AACJ;AAaO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,IAAI,gBAAgB;AAClC,SAAK,SAAS,IAAI,gBAAgB;AAClC,SAAK,aAAa,IAAI,YAAY,IAAI,OAAO,GAAE,CAAC,GAAG,IAAI,MAAM,GAAE,CAAC,CAAC;AACjE,SAAK,aAAa,IAAI,YAAY,IAAI,OAAO,GAAE,CAAC,GAAG,IAAI,MAAM,GAAE,CAAC,CAAC;AACjE,SAAK,WAAW;AAAA,EACpB;AACJ;AAWO,IAAM,mBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,IAAI,OAAO,GAAE,CAAC;AAC5B,SAAK,SAAS,IAAI,OAAO,GAAE,CAAC;AAC5B,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,eAAe;AAAA,EACxB;AACJ;AAYO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,cACA;AACI,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,iBAAgB;AAC/B,OAAG,KAAK,KAAK,GAAG,MAAM;AACtB,OAAG,KAAK,KAAK,GAAG,MAAM;AACtB,OAAG,IAAI,KAAK,EAAE,MAAM;AACpB,OAAG,IAAI,KAAK;AACZ,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AAEjB,WAAO;AAAA,EACX;AACJ;AAUO,IAAM,YAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,KAAK,IAAI,gBAAgB;AAC9B,SAAK,KAAK,IAAI,gBAAgB;AAC9B,SAAK,KAAK,IAAI,gBAAgB;AAC9B,SAAK,QAAQ;AAAA,EACjB;AACJ;AAYO,IAAM,uBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,IAAI,gBAAgB;AAClC,SAAK,SAAS,IAAI,gBAAgB;AAClC,SAAK,aAAa,IAAI,YAAY,IAAI,OAAO,GAAE,CAAC,GAAG,IAAI,MAAM,GAAE,CAAC,CAAC;AACjE,SAAK,aAAa,IAAI,YAAY,IAAI,OAAO,GAAE,CAAC,GAAG,IAAI,MAAM,GAAE,CAAC,CAAC;AACjE,SAAK,eAAe,IAAI,OAAO,GAAE,CAAC;AAClC,SAAK,cAAc;AAAA,EACvB;AACJ;AAWO,IAAM,UAAN,MAAM,SACb;AAAA,EACI,YAAYC,KAAI,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAC5D;AACI,SAAK,cAAcA;AACnB,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AAAA,EACd;AAAA,EAEA,QACA;AACI,WAAO,IAAI,SAAQ,KAAK,YAAY,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAAA,EACnH;AACJ;AAWO,IAAM,aAAN,MAAM,YACb;AAAA,EACI,YAAY,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,OAAO,GAC/E;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAChB;AAAA,EAEA,QACA;AACI,WAAO,IAAI,YAAW,KAAK,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK,IAAI;AAAA,EACvH;AACJ;AAEO,IAAM,aAAa;AAAA,EACtB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,sBAAsB;AAC1B;AAQO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,QAAQ,WAAW;AACxB,SAAK,IAAI;AAAA,EACb;AACJ;AAgBO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,KAAK;AACV,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,QACA;AACI,UAAM,QAAQ,IAAI,iBAAgB;AAClC,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,KAAK;AACtB,UAAM,aAAa,KAAK;AACxB,UAAM,gBAAgB,KAAK;AAC3B,UAAM,iBAAiB,KAAK;AAC5B,UAAM,mBAAmB,KAAK;AAC9B,UAAM,iBAAiB,KAAK;AAC5B,UAAM,KAAK,KAAK;AAChB,UAAM,YAAY,KAAK;AAEvB,WAAO;AAAA,EACX;AAAA,EAEA,QACA;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,KAAK;AACV,SAAK,YAAY;AAEjB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,IACP;AACI,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,WAAW,KAAK;AACnB,OAAG,WAAW,KAAK;AACnB,OAAG,WAAW,KAAK;AACnB,OAAG,WAAW,KAAK;AACnB,OAAG,aAAa,KAAK;AACrB,OAAG,gBAAgB,KAAK;AACxB,OAAG,iBAAiB,KAAK;AACzB,OAAG,mBAAmB,KAAK;AAC3B,OAAG,iBAAiB,KAAK;AACzB,OAAG,KAAK,KAAK;AACb,OAAG,YAAY,KAAK;AAAA,EACxB;AACJ;AASO,IAAM,aAAN,MAAM,YACb;AAAA,EACI,YAAYC,MAAK,IAAI,gBAAgB,GAAGC,MAAK,IAAI,gBAAgB,GACjE;AACI,SAAK,SAAS,CAAED,KAAIC,GAAG;AACvB,SAAK,UAAU,KAAK,UAAU;AAC9B,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,QACA;AACI,UAAM,QAAQ,IAAI,YAAW;AAE7B,SAAK,OAAO,KAAK;AAEjB,WAAO;AAAA,EACX;AAAA,EAEA,QACA;AACI,QAAI,KAAK,OAAO,CAAC,GACjB;AACI,WAAK,OAAO,CAAC,EAAE,MAAM;AAAA,IACzB;AAEA,QAAI,KAAK,OAAO,CAAC,GACjB;AACI,WAAK,OAAO,CAAC,EAAE,MAAM;AAAA,IACzB;AAEA,SAAK,UAAU,KAAK,UAAU;AAC9B,SAAK,aAAa;AAElB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,UACP;AACI,SAAK,OAAO,CAAC,EAAE,OAAO,SAAS,OAAO,CAAC,CAAC;AACxC,SAAK,OAAO,CAAC,EAAE,OAAO,SAAS,OAAO,CAAC,CAAC;AACxC,aAAS,UAAU,KAAK;AACxB,aAAS,UAAU,KAAK;AACxB,aAAS,aAAa,KAAK;AAAA,EAC/B;AACJ;AAeO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,eAAe;AAGpB,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EACpB;AACJ;;;AC3nBO,SAAS,cAChB;AACI,SAAO,oBAAI,IAAI;AACnB;AAEO,SAAS,aAAa,KAC7B;AACI,MAAI,MAAM;AACd;AAEO,SAAS,WAAW,KAC3B;AACI,MAAI,MAAM;AACd;AAEO,SAAS,cAAc,KAAK,KACnC;AACI,SAAO,IAAI,IAAI,GAAG;AACtB;AAEO,SAAS,SAAS,KAAK,KAC9B;AACI,MAAI,IAAI,IAAI,GAAG,GACf;AACI,WAAO;AAAA,EACX;AACA,MAAI,IAAI,KAAK,CAAC;AAEd,SAAO;AACX;AAEO,SAAS,YAAY,KAAK,KACjC;AACI,SAAO,IAAI,OAAO,GAAG;AACzB;;;AC1CO,IAAM,oBAAoB,CAAC,IAAI,OAAO,KAAK,KAAK,OAAO,EAAE,KAAK,MAAM,OAAO,EAAE,IAAI,OAAO,EAAE,KAAK,MAAM,OAAO,EAAE;;;ACM9G,IAAM,mBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EAEnB;AACJ;AAEA,IAAM,eAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EAEhB;AACJ;AAEO,SAAS,uBAAuB,UACvC;AACI,QAAM,YAAY,IAAI,iBAAiB;AACvC,YAAU,OAAO,CAAC;AAClB,YAAU,UAAU,CAAC;AAErB,SAAO;AACX;AAEO,SAAS,wBAAwB,WACxC;AACI,YAAU,OAAO;AACjB,YAAU,UAAU;AACxB;AAEO,SAAS,oBAAoB,OAAO,MAAM,MAAM,OAAO,MAC9D;AACI,UAAQ,OAAO,QAAQ,CAAC;AACxB,QAAM,QAAQ,IAAI,aAAa;AAC/B,QAAM,OAAO;AACb,QAAM,OAAO;AACb,QAAM,OAAO,CAAC;AAEd,WAAS,IAAI,GAAG,IAAI,MAAM,KAC1B;AACI,QAAI,MACJ;AAAE,YAAM,KAAK,KAAK,KAAK,CAAC;AAAA,IAAG,OAE3B;AAAE,YAAM,KAAK,KAAK,IAAI;AAAA,IAAG;AAAA,EAC7B;AACA,QAAM,QAAQ,KAAK,KAAK;AAExB,SAAO,MAAM;AACjB;AAEO,SAAS,gBAAgB,OAAO,KACvC;AACI,QAAM,aAAa,MAAM,QAAQ;AACjC,UAAQ,OAAO,aAAa,CAAC;AAC7B,QAAM,QAAQ,MAAM,QAAQ,aAAa,CAAC;AAC1C,UAAQ,OAAO,MAAM,QAAQ,GAAG;AAChC,UAAQ,OAAO,MAAM,QAAQ,CAAC;AAC9B,QAAM,QAAQ,IAAI;AACtB;AAWO,SAAS,qBAAqB,OACrC;AACI,SAAO,MAAM,QAAQ;AACzB;;;AC5EO,SAAS,QAAQ,MAAM,eAAe,MAC7C;AACI,QAAM,MAAM,CAAC;AAEb,MAAI,cACJ;AACI,aAAS,IAAI,GAAG,IAAI,MAAM,KAC1B;AAAE,UAAI,CAAC,IAAI,aAAa;AAAA,IAAG;AAAA,EAC/B;AAEA,SAAO;AACX;AAEO,SAAS,OAAO,KAAK,SAAS,eAAe,MACpD;AACI,QAAM,UAAU,IAAI;AAEpB,MAAI,cACJ;AACI,aAAS,IAAI,SAAS,IAAI,SAAS,KACnC;AAAE,UAAI,CAAC,IAAI,aAAa;AAAA,IAAG;AAAA,EAC/B;AAEA,SAAO;AACX;;;ACvBO,IAAM,eAAe;AAkCrB,SAAS,oBAChB;AACI,QAAM,MAAM,IAAI,WAAW;AAC3B,MAAI,UAAU,IAAI,OAAO,GAAK,GAAK;AACnC,MAAI,oBAAoB,IAAMC;AAC9B,MAAI,uBAAuB,KAAOA;AAClC,MAAI,yBAAyB,IAAMA;AACnC,MAAI,eAAe;AACnB,MAAI,sBAAsB;AAC1B,MAAI,aAAa;AACjB,MAAI,oBAAoB;AACxB,MAAI,wBAAwB,MAAQA;AACpC,MAAI,cAAc;AAClB,MAAI,mBAAmB;AAEvB,SAAO;AACX;AAwBO,SAAS,mBAChB;AACI,QAAM,MAAM,IAAI,UAAU;AAC1B,MAAI,OAAO,WAAW;AACtB,MAAI,WAAW,IAAI,OAAO,GAAG,CAAC;AAC9B,MAAI,WAAW,IAAI,MAAM,GAAG,CAAC;AAC7B,MAAI,iBAAiB,IAAI,OAAO,GAAG,CAAC;AACpC,MAAI,kBAAkB;AACtB,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AACrB,MAAI,eAAe;AACnB,MAAI,iBAAiB,OAAOA;AAC5B,MAAI,WAAW;AACf,MAAI,cAAc;AAClB,MAAI,UAAU;AACd,MAAI,gBAAgB;AACpB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,MAAI,iBAAiB;AACrB,MAAI,oBAAoB;AAExB,SAAO;AACX;AAaO,SAAS,kBAChB;AACI,QAAM,SAAS,IAAI,SAAS;AAC5B,SAAO,eAAe;AACtB,SAAO,WAAW;AAClB,SAAO,aAAa;AAEpB,SAAO;AACX;AAYO,SAAS,uBAChB;AACI,QAAM,SAAS,IAAI,cAAc;AACjC,SAAO,eAAe;AACtB,SAAO,WAAW;AAElB,SAAO;AACX;AAiBO,SAAS,oBAChB;AACI,QAAM,MAAM,IAAI,WAAW;AAC3B,MAAI,WAAW;AACf,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,SAAS,gBAAgB;AAC7B,MAAI,qBAAqB;AACzB,MAAI,sBAAsB;AAE1B,SAAO;AACX;AAaO,SAAS,oBAChB;AACI,QAAM,MAAM,IAAI,WAAW;AAC3B,MAAI,WAAW;AACf,MAAI,SAAS,gBAAgB;AAE7B,SAAO;AACX;;;ACvLO,IAAM,aAAa;AAAA,EACtB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,kBAAkB;AACtB;AAEO,IAAM,cAAc;AAAA,EACvB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,mBAAmB;AACvB;AAEO,IAAM,cAAc;AAAA,EACvB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AAChB;AAaO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,QAAQ,IAAI,OAAO,GAAG,CAAC;AAC5B,SAAK,SAAS,IAAI,OAAO,GAAG,CAAC;AAC7B,SAAK,WAAW;AAChB,SAAK,MAAM;AAAA,EACf;AACJ;AAyBO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU,IAAI,OAAO,GAAG,CAAC;AAC9B,SAAK,uBAAuB;AAC5B,SAAK,yBAAyB;AAC9B,SAAK,oBAAoB;AACzB,SAAK,eAAe;AACpB,SAAK,sBAAsB;AAC3B,SAAK,aAAa;AAClB,SAAK,oBAAoB;AACzB,SAAK,wBAAwB;AAC7B,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,cAAc;AAAA,EAGvB;AACJ;AAuBO,IAAM,YAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO,WAAW;AACvB,SAAK,WAAW,IAAI,OAAO,GAAG,CAAC;AAC/B,SAAK,WAAW,IAAI,MAAM,GAAG,CAAC;AAC9B,SAAK,iBAAiB,IAAI,OAAO,GAAG,CAAC;AACrC,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,iBAAiB;AACtB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,iBAAiB;AACtB,SAAK,oBAAoB;AAAA,EAC7B;AACJ;AAsBO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,cAAc,WAAW;AAC9B,SAAK,WAAW;AAGhB,SAAK,qBAAqB;AAG1B,SAAK,sBAAsB;AAG3B,SAAK,kBAAkB;AAKvB,SAAK,uBAAuB;AAK5B,SAAK,uBAAuB;AAAA,EAChC;AACJ;AAeO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,SAAS;AAAA,EAClB;AACJ;AAwBO,IAAM,qBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,SAAS;AACd,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAgBO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAeO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,SAAS,IAAI,OAAO,GAAG,CAAC;AAC7B,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAwBO,IAAM,sBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,aAAa,IAAI,OAAO,GAAG,CAAC;AACjC,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAwBO,IAAM,qBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAkBO,IAAM,iBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB;AAC3B,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAuBO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,eAAe,IAAI,OAAO,GAAG,CAAC;AACnC,SAAK,aAAa,IAAI,OAAO,GAAG,CAAC;AACjC,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAAA,EACpB;AACJ;AAQO,IAAM,0BAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AAAA,EAC1B;AACJ;AAQO,IAAM,wBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AAAA,EAC1B;AACJ;AAUO,IAAM,iBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,WAAW;AAAA,EACpB;AACJ;AASO,IAAM,2BAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EACpB;AACJ;AAQO,IAAM,yBAAN,MACP;AAAA,EACI,YAAY,IAAI,MAAM,IAAI,MAC1B;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EACpB;AACJ;AAWO,IAAM,oBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,gBAAgB;AAAA,EACzB;AACJ;AAYO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EACpB;AACJ;AAUO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,YAAY;AACjB,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,aAAa;AAAA,EACtB;AACJ;AAQO,IAAM,eAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,aAAa;AAClB,SAAK,YAAY;AAAA,EACrB;AACJ;AAWO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,aAAa;AAAA,EACtB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,eAAe;AAAA;AAAA,EACf,wBAAwB;AAAA,EACxB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,qBAAqB;AACzB;AAoBO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,kBAAkB;AACvB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,mBAAmB;AACxB,SAAK,iBAAiB,IAAI,OAAO;AACjC,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,eAAe;AACpB,SAAK,kBAAkB;AACvB,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB;AAC3B,SAAK,uBAAuB;AAC5B,SAAK,UAAU;AAAA,EACnB;AACJ;AAaO,IAAM,WAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,aAAa;AAAA,EACtB;AACJ;AAQO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,eAAe;AACpB,SAAK,WAAW;AAAA,EACpB;AACJ;;;AC35BO,IAAM,WAAN,MACP;AAAA,EACI,YAAY,MACZ;AACI,SAAK,OAAO;AACZ,SAAK,YAAY,CAAC;AAClB,SAAK,YAAY;AAAA,EACrB;AACJ;AAEO,SAAS,gBAAgB,MAChC;AACI,SAAO,KAAK;AAChB;AAEO,SAAS,eAAe,OAAO,QACtC;AACI,SAAO,IAAI,SAAS,IAAI;AAC5B;AAEO,SAAS,gBAAgB,MAChC;AACI,OAAK,YAAY;AACjB,OAAK,YAAY;AACrB;AAEO,SAAS,UAAU,MAC1B;AACI,MAAI,KAAK,UAAU,SAAS,GAC5B;AACI,WAAO,KAAK,UAAU,IAAI;AAAA,EAC9B;AAEA,QAAM,KAAK,KAAK;AAChB,OAAK;AAEL,SAAO;AACX;AAEO,SAAS,SAAS,MAAM,IAC/B;AACI,MAAI,OAAO,KAAK,YAAY,GAC5B;AACI,SAAK;AAEL;AAAA,EACJ;AAEA,OAAK,UAAU,KAAK,EAAE;AAC1B;AAEO,SAAS,aAAa,MAC7B;AACI,SAAO,KAAK,YAAY,KAAK,UAAU;AAC3C;;;ACCO,SAAS,oBAAoB,OAAO,MAC3C;AACI,QAAMC,MAAK,IAAI,YAAY;AAC3B,EAAAA,IAAG,IAAI,MAAM,QAAQ,IAAM,MAAM,MAAM,EAAE,GAAG,QAAQ,MAAM,MAAM,EAAE,CAAC;AAEnE,QAAMC,KAAI,IAAI;AAAA,KAAO,IAAM,QAAQ,MAAM,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,KAC3D,IAAM,QAAQ,MAAM,GAAG,IAAI,OAAO,MAAM,GAAG;AAAA,EAAC;AAEjD,EAAAD,IAAG,IAAI,eAAeC,EAAC;AAEvB,EAAAD,IAAG,IAAI,MAAMA,IAAG,GAAG,eAAeA,IAAG,GAAG,MAAM,WAAW,CAAC;AAE1D,SAAOA;AACX;AAmBA,IAAM,WAAW,IAAI,wBAAwB;AAEtC,SAAS,kBAAkB,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KACrE;AACI,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AACjB,QAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,QAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,QAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,QAAM,MAAM,KAAK,MAAM,KAAK;AAE5B,MAAI,MAAM,UAAU,MAAM,QAC1B;AACI,QAAI,OAAO,QACX;AACI,kBAAY,aAAa,CAAC,MAAM,KAAK,GAAK,CAAG;AAC7C,kBAAY;AAAA,IAChB,WACS,OAAO,QAChB;AACI,kBAAY;AACZ,kBAAY,aAAa,MAAM,KAAK,GAAK,CAAG;AAAA,IAChD;AAAA,EACJ,OAEA;AACI,UAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,UAAM,QAAQ,MAAM,MAAM,MAAM;AAEhC,QAAI,KAAK;AAET,QAAI,UAAU,GACd;AACI,WAAK,cAAc,MAAM,MAAM,MAAM,OAAO,OAAO,GAAK,CAAG;AAAA,IAC/D;AAEA,QAAI,MAAM,MAAM,KAAK,OAAO;AAE5B,QAAI,KAAK,GACT;AACI,WAAK;AACL,WAAK,aAAa,CAAC,MAAM,KAAK,GAAK,CAAG;AAAA,IAC1C,WACS,KAAK,GACd;AACI,WAAK;AACL,WAAK,cAAc,MAAM,OAAO,KAAK,GAAK,CAAG;AAAA,IACjD;AAEA,gBAAY;AACZ,gBAAY;AAAA,EAChB;AAEA,QAAM,YAAY,MAAM,YAAY;AACpC,QAAM,YAAY,MAAM,YAAY;AACpC,QAAM,YAAY,MAAM,YAAY;AACpC,QAAM,YAAY,MAAM,YAAY;AAEpC,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,YAAY;AACvB,QAAM,kBAAkB,KAAK,KAAK,KAAK;AAEvC,WAAS,WAAW,SAAS,WAAW;AACxC,WAAS,YAAY;AACrB,WAAS,YAAY;AACrB,WAAS,kBAAkB;AAE3B,SAAO;AACX;AAWO,SAAS,YAAY,UAAU,OAAO,QAC7C;AACI,UAAQ,OAAO,SAAS,uBAAuB;AAE/C,UAAQ,KAAK,IAAI,OAAO,uBAAuB;AAE/C,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,CAAC;AAChB,QAAM,QAAQ;AACd,QAAM,SAAS;AAEf,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAM,OAAO,CAAC,IAAI,SAAS,CAAC,EAAE,MAAM;AAAA,EACxC;AAEA,SAAO;AACX;AAEA,SAAS,UAAU,IAAI,IAAI,IAAI,IAC/B;AACI,SAAO,IAAI,OAAO,KAAK,GAAG,IAAI,KAAK,GAAG,GAAG,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC;AAClE;AAEA,SAAS,UAAU,IAAI,IAAI,IAAI,IAAI,IAAI,IACvC;AACI,SAAO,IAAI,OAAO,KAAK,GAAG,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,GAAG,KAAK,GAAG,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC;AAC1F;AAEA,SAAS,cAAc,OAAO,WAC9B;AACI,MAAI,YAAY;AAChB,MAAI,YAAY,MAAM,MAAM,OAAO,CAAC,GAAG,SAAS;AAEhD,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,UAAM,QAAQ,MAAM,MAAM,OAAO,CAAC,GAAG,SAAS;AAE9C,QAAI,QAAQ,WACZ;AACI,kBAAY;AACZ,kBAAY;AAAA,IAChB;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,SAAS,uBAAuB,OAAO,QAAQ,YAAY,QAAQ,YACnE;AACI,QAAM,IAAI,IAAI,UAAU;AACxB,IAAE,QAAQ,MAAM;AAEhB,QAAM,WAAW,CAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAG;AAEpC,WAAS,IAAI,GAAG,IAAI,EAAE,OAAO,EAAE,GAC/B;AACI,UAAM,IAAI,SAAS,CAAC;AACpB,MAAE,SAAS,MAAM,OAAO,CAAC;AACzB,MAAE,SAAS,MAAM,OAAO,CAAC;AACzB,UAAM,UAAU,OAAO,OAAO,EAAE,MAAM;AACtC,UAAM,UAAU,OAAO,OAAO,EAAE,MAAM;AACtC,MAAE,KAAK,iBAAiB,YAAY,OAAO;AAC3C,MAAE,KAAK,iBAAiB,YAAY,OAAO;AAC3C,MAAE,IAAI,MAAM,EAAE,IAAI,EAAE,EAAE;AACtB,MAAE,IAAI;AAAA,EACV;AAEA,MAAI,EAAE,UAAU,GAChB;AACI,UAAM,IAAI,SAAS,CAAC;AACpB,MAAE,SAAS;AACX,MAAE,SAAS;AACX,UAAM,UAAU,OAAO,OAAO,CAAC;AAC/B,UAAM,UAAU,OAAO,OAAO,CAAC;AAC/B,MAAE,KAAK,iBAAiB,YAAY,OAAO;AAC3C,MAAE,KAAK,iBAAiB,YAAY,OAAO;AAC3C,MAAE,IAAI,MAAM,EAAE,IAAI,EAAE,EAAE;AACtB,MAAE,IAAI;AACN,MAAE,QAAQ;AAAA,EACd;AAEA,SAAO;AACX;AAEA,SAAS,mBAAmB,OAAO,SACnC;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,WAAW,CAAE,QAAQ,IAAI,QAAQ,IAAI,QAAQ,EAAG;AAEtD,WAAS,IAAI,GAAG,IAAI,QAAQ,OAAO,EAAE,GACrC;AACI,UAAM,OAAO,CAAC,IAAI,SAAS,CAAC,EAAE;AAC9B,UAAM,OAAO,CAAC,IAAI,SAAS,CAAC,EAAE;AAAA,EAClC;AACJ;AAEA,SAAS,gCAAgC,SACzC;AACI,UAAQ,QAAQ,OAChB;AAAA,IACI,KAAK;AACD,aAAO,MAAM,QAAQ,GAAG,CAAC;AAAA,IAE7B,KAAK;AACD,YAAM,MAAM,MAAM,QAAQ,GAAG,GAAG,QAAQ,GAAG,CAAC;AAC5C,YAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,GAAG,CAAC,CAAC;AAE5C,UAAI,MAAM,GACV;AACI,eAAO,WAAW,GAAG;AAAA,MACzB,OAEA;AACI,eAAO,YAAY,GAAG;AAAA,MAC1B;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,EAC9B;AACJ;AAEA,SAAS,6BAA6B,GACtC;AACI,UAAQ,EAAE,OACV;AAAA,IACI,KAAK;AACD,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,IAE1B,KAAK;AACD,aAAO,EAAE,GAAG;AAAA,IAEhB,KAAK;AACD,aAAO,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,CAAC;AAAA,IAEnD,KAAK;AACD,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,IAE1B;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,EAC9B;AACJ;AAEA,SAAS,8BAA8B,GAAG,GAAG,GAC7C;AACI,UAAQ,EAAE,OACV;AAAA,IACI,KAAK;AACD,cAAQ,OAAO,KAAK;AAEpB;AAAA,IAEJ,KAAK;AACD,QAAE,IAAI,EAAE,GAAG,GAAG;AACd,QAAE,IAAI,EAAE,GAAG,GAAG;AACd,QAAE,IAAI,EAAE,GAAG,GAAG;AACd,QAAE,IAAI,EAAE,GAAG,GAAG;AAEd;AAAA,IAEJ,KAAK;AACD,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AAClD,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AAClD,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AAClD,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AAElD;AAAA,IAEJ,KAAK;AACD,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AACnE,QAAE,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE;AACnE,QAAE,IAAI,EAAE;AACR,QAAE,IAAI,EAAE;AAER;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAEpB;AAAA,EACR;AACJ;AAEA,SAAS,gBAAgB,GACzB;AACI,QAAM,KAAK,EAAE,GAAG;AAChB,QAAM,KAAK,EAAE,GAAG;AAChB,QAAM,MAAM,MAAM,IAAI,EAAE;AAExB,QAAM,QAAQ,CAAC,MAAM,IAAI,GAAG;AAE5B,MAAI,SAAS,GACb;AACI,MAAE,GAAG,IAAI;AACT,MAAE,QAAQ;AAEV;AAAA,EACJ;AAEA,QAAM,QAAQ,MAAM,IAAI,GAAG;AAE3B,MAAI,SAAS,GACb;AACI,MAAE,GAAG,IAAI;AACT,MAAE,QAAQ;AACV,MAAE,KAAK,EAAE;AAET;AAAA,EACJ;AAEA,QAAM,UAAU,KAAO,QAAQ;AAC/B,IAAE,GAAG,IAAI,QAAQ;AACjB,IAAE,GAAG,IAAI,QAAQ;AACjB,IAAE,QAAQ;AACd;AAEA,SAAS,gBAAgB,GACzB;AACI,QAAM,KAAK,EAAE,GAAG;AAChB,QAAM,KAAK,EAAE,GAAG;AAChB,QAAM,KAAK,EAAE,GAAG;AAEhB,QAAM,MAAM,MAAM,IAAI,EAAE;AACxB,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ;AACd,QAAM,QAAQ,CAAC;AAEf,QAAM,MAAM,MAAM,IAAI,EAAE;AACxB,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ;AACd,QAAM,QAAQ,CAAC;AAEf,QAAM,MAAM,MAAM,IAAI,EAAE;AACxB,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAM,QAAQ;AACd,QAAM,QAAQ,CAAC;AAEf,QAAM,OAAO,QAAQ,KAAK,GAAG;AAE7B,QAAM,SAAS,OAAO,QAAQ,IAAI,EAAE;AACpC,QAAM,SAAS,OAAO,QAAQ,IAAI,EAAE;AACpC,QAAM,SAAS,OAAO,QAAQ,IAAI,EAAE;AAEpC,MAAI,SAAS,KAAO,SAAS,GAC7B;AACI,MAAE,GAAG,IAAI;AACT,MAAE,QAAQ;AAEV;AAAA,EACJ;AAEA,MAAI,QAAQ,KAAO,QAAQ,KAAO,UAAU,GAC5C;AACI,UAAM,UAAU,KAAO,QAAQ;AAC/B,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,QAAQ;AAEV;AAAA,EACJ;AAEA,MAAI,QAAQ,KAAO,QAAQ,KAAO,UAAU,GAC5C;AACI,UAAM,UAAU,KAAO,QAAQ;AAC/B,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,QAAQ;AACV,MAAE,KAAK,EAAE,GAAG,MAAM;AAElB;AAAA,EACJ;AAEA,MAAI,SAAS,KAAO,SAAS,GAC7B;AACI,MAAE,GAAG,IAAI;AACT,MAAE,QAAQ;AACV,MAAE,KAAK,EAAE,GAAG,MAAM;AAElB;AAAA,EACJ;AAEA,MAAI,SAAS,KAAO,SAAS,GAC7B;AACI,MAAE,GAAG,IAAI;AACT,MAAE,QAAQ;AACV,MAAE,KAAK,EAAE,GAAG,MAAM;AAElB;AAAA,EACJ;AAEA,MAAI,QAAQ,KAAO,QAAQ,KAAO,UAAU,GAC5C;AACI,UAAM,UAAU,KAAO,QAAQ;AAC/B,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,GAAG,IAAI,QAAQ;AACjB,MAAE,QAAQ;AACV,MAAE,KAAK,EAAE,GAAG,MAAM;AAElB;AAAA,EACJ;AAEA,QAAM,WAAW,KAAO,SAAS,SAAS;AAC1C,IAAE,GAAG,IAAI,SAAS;AAClB,IAAE,GAAG,IAAI,SAAS;AAClB,IAAE,GAAG,IAAI,SAAS;AAClB,IAAE,QAAQ;AACd;AAEA,IAAM,KAAK,IAAI,OAAO;AAsBf,SAAS,gBAAgB,OAAO,OAAO,WAAW,iBACzD;AACI,QAAM,SAAS,IAAI,iBAAiB;AAEpC,QAAM,SAAS,MAAM;AACrB,QAAM,SAAS,MAAM;AAErB,QAAM,aAAa,MAAM;AACzB,QAAM,aAAa,MAAM;AAEzB,QAAM,UAAU,uBAAuB,OAAO,QAAQ,YAAY,QAAQ,UAAU;AAEpF,MAAI,eAAe;AAEnB,MAAI,cAAc,QAAQ,eAAe,iBACzC;AACI,cAAU,YAAY,IAAI;AAC1B,oBAAgB;AAAA,EACpB;AAEA,QAAM,WAAW,CAAE,QAAQ,IAAI,QAAQ,IAAI,QAAQ,EAAG;AACtD,QAAM,aAAa;AAEnB,QAAM,QAAQ,CAAE,GAAG,GAAG,CAAE;AACxB,QAAM,QAAQ,CAAE,GAAG,GAAG,CAAE;AAExB,UAAQ,OAAO,QAAQ,OAAO,QAAQ,EAAE;AAExC,MAAI,OAAO;AAEX,SAAO,OAAO,YACd;AACI,UAAM,YAAY,QAAQ;AAE1B,aAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,YAAM,CAAC,IAAI,SAAS,CAAC,EAAE;AACvB,YAAM,CAAC,IAAI,SAAS,CAAC,EAAE;AAAA,IAC3B;AAEA,YAAQ,QAAQ,OAChB;AAAA,MACI,KAAK;AACD;AAAA,MAEJ,KAAK;AACD,wBAAgB,OAAO;AAEvB;AAAA,MAEJ,KAAK;AACD,wBAAgB,OAAO;AAEvB;AAAA,MAEJ;AACI,gBAAQ,OAAO,KAAK;AAEpB;AAAA,IACR;AAEA,QAAI,QAAQ,UAAU,GACtB;AACI;AAAA,IACJ;AAEA,QAAI,cAAc,QAAQ,eAAe,iBACzC;AACI,gBAAU,YAAY,IAAI;AAC1B,sBAAgB;AAAA,IACpB;AAEA,UAAM,IAAI,gCAAgC,OAAO;AAEjD,QAAI,MAAM,GAAG,CAAC,IAAI,MAAM,KACxB;AACI;AAAA,IACJ;AAEA,UAAM,SAAS,SAAS,QAAQ,KAAK;AACrC,WAAO,SAAS,cAAc,QAAQ,kBAAkB,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC;AAC/E,WAAO,KAAK,iBAAiB,YAAY,OAAO,OAAO,OAAO,MAAM,CAAC;AACrE,WAAO,SAAS,cAAc,QAAQ,kBAAkB,WAAW,GAAG,CAAC,CAAC;AACxE,WAAO,KAAK,iBAAiB,YAAY,OAAO,OAAO,OAAO,MAAM,CAAC;AACrE,WAAO,IAAI,MAAM,OAAO,IAAI,OAAO,EAAE;AAErC,MAAE;AAEF,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,UAAI,OAAO,WAAW,MAAM,CAAC,KAAK,OAAO,WAAW,MAAM,CAAC,GAC3D;AACI,oBAAY;AAEZ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,WACJ;AACI;AAAA,IACJ;AAEA,MAAE,QAAQ;AAAA,EACd;AAEA,MAAI,cAAc,QAAQ,eAAe,iBACzC;AACI,cAAU,YAAY,IAAI;AAC1B,oBAAgB;AAAA,EACpB;AAEA,gCAA8B,OAAO,QAAQ,OAAO,QAAQ,OAAO;AACnE,SAAO,WAAW,WAAW,OAAO,QAAQ,OAAO,MAAM;AACzD,SAAO,aAAa;AACpB,SAAO,eAAe;AAEtB,qBAAmB,OAAO,OAAO;AAEjC,MAAI,MAAM,UACV;AACI,QAAI,OAAO,WAAW,KACtB;AACI,SAAG,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,OAAO;AAC9C,SAAG,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,OAAO;AAC9C,aAAO,OAAO,IAAI,GAAG;AACrB,aAAO,OAAO,IAAI,GAAG;AACrB,aAAO,OAAO,IAAI,GAAG;AACrB,aAAO,OAAO,IAAI,GAAG;AACrB,aAAO,WAAW;AAAA,IACtB,OAEA;AACI,YAAM,KAAK,OAAO;AAClB,YAAM,KAAK,OAAO;AAClB,aAAO,WAAW,KAAK,IAAI,GAAK,OAAO,WAAW,KAAK,EAAE;AACzD,YAAM,SAAS,YAAY,MAAM,OAAO,QAAQ,OAAO,MAAM,CAAC;AAC9D,YAAM,WAAW,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,OAAO;AAC7B,aAAO,OAAO,KAAK;AACnB,aAAO,OAAO,KAAK;AACnB,aAAO,OAAO,KAAK;AACnB,aAAO,OAAO,KAAK;AAAA,IACvB;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,IAAM,WAAW,IAAI,OAAO,GAAG,CAAC;AAChC,IAAM,YAAY,IAAI,OAAO,GAAG,CAAC;AAwB1B,SAAS,YAAY,OAC5B;AACI,QAAM,SAAS,IAAI,aAAa,WAAW,QAAQ;AACnD,SAAO,WAAW,MAAM;AAExB,QAAM,SAAS,MAAM;AAErB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAMA,MAAK,mBAAmB,KAAK,GAAG;AAEtC,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,QAAQ,MAAM,OAAO;AAC5B,SAAO,SAAS,MAAM,OAAO;AAC7B,SAAO,SAAS,CAAC;AAEjB,WAAS,IAAI,GAAG,IAAI,OAAO,OAAO,EAAE,GACpC;AACI,WAAO,OAAO,CAAC,IAAI,iBAAiBA,KAAI,MAAM,OAAO,OAAO,CAAC,CAAC;AAAA,EAClE;AAEA,QAAM,SAAS,OAAO,SAAS,OAAO;AAEtC,QAAM,IAAI,eAAeA,IAAG,GAAG,MAAM,YAAY;AACjD,MAAI,SAAS;AACb,QAAM,cAAc,MAAM;AAE1B,QAAM,UAAU,IAAI,UAAU;AAC9B,UAAQ,QAAQ;AAChB,UAAQ,KAAK,IAAI,gBAAgB;AACjC,UAAQ,KAAK,IAAI,gBAAgB;AACjC,UAAQ,KAAK,IAAI,gBAAgB;AAEjC,QAAM,WAAW,CAAE,QAAQ,IAAI,QAAQ,IAAI,QAAQ,EAAG;AAEtD,MAAI,SAAS,cAAc,QAAQ,MAAM,CAAC,CAAC;AAC3C,MAAI,KAAK,OAAO,OAAO,MAAM;AAC7B,MAAI,SAAS,cAAc,QAAQ,CAAC;AACpC,MAAI,KAAK,OAAO,OAAO,MAAM;AAC7B,MAAI,IAAI,MAAM,IAAI,EAAE;AAEpB,QAAM,aAAa;AACnB,QAAM,QAAQ,KAAK,IAAI,YAAY,SAAS,UAAU;AAEtD,QAAM,aAAa;AACnB,MAAI,OAAO;AAEX,SAAO,OAAO,cAAc,SAAS,CAAC,IAAI,QAAQ,MAAM,YACxD;AACI,YAAQ,OAAO,QAAQ,QAAQ,CAAC;AAEhC,WAAO,cAAc;AAErB,aAAS,cAAc,QAAQ,MAAM,CAAC,CAAC;AACvC,SAAK,OAAO,OAAO,MAAM;AACzB,aAAS,cAAc,QAAQ,CAAC;AAChC,SAAK,OAAO,OAAO,MAAM;AACzB,UAAME,KAAI,MAAM,IAAI,EAAE;AAEtB,QAAI,YAAY,CAAC;AAEjB,UAAM,KAAK,MAAM,GAAGA,EAAC;AACrB,UAAM,KAAK,MAAM,GAAG,CAAC;AAErB,QAAI,KAAK,QAAQ,SAAS,IAC1B;AACI,UAAI,MAAM,GACV;AACI,eAAO;AAAA,MACX;AAEA,gBAAU,KAAK,SAAS;AAExB,UAAI,SAAS,aACb;AACI,eAAO;AAAA,MACX;AAEA,cAAQ,QAAQ;AAAA,IACpB;AAEA,UAAM,SAAS,SAAS,QAAQ,KAAK;AACrC,WAAO,SAAS;AAChB,WAAO,KAAK,IAAI,OAAO,GAAG,IAAI,SAAS,EAAE,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;AAC/D,WAAO,SAAS;AAChB,WAAO,KAAK,GAAG,MAAM;AACrB,WAAO,IAAI,MAAM,OAAO,IAAI,OAAO,EAAE;AACrC,WAAO,IAAI;AACX,YAAQ,SAAS;AAEjB,YAAQ,QAAQ,OAChB;AAAA,MACI,KAAK;AACD;AAAA,MAEJ,KAAK;AACD,wBAAgB,OAAO;AAEvB;AAAA,MAEJ,KAAK;AACD,wBAAgB,OAAO;AAEvB;AAAA,MAEJ;AACI,gBAAQ,OAAO,KAAK;AAAA,IAC5B;AAEA,QAAI,QAAQ,UAAU,GACtB;AACI,aAAO;AAAA,IACX;AAEA,QAAI,6BAA6B,OAAO;AAExC,MAAE;AAAA,EACN;AAEA,MAAI,SAAS,KAAK,WAAW,GAC7B;AACI,WAAO;AAAA,EACX;AAEA,QAAM,SAAS,IAAI,OAAO;AAC1B,QAAM,SAAS,IAAI,OAAO;AAC1B,gCAA8B,QAAQ,QAAQ,OAAO;AAErD,QAAM,IAAI,YAAY,MAAM,CAAC,CAAC;AAC9B,QAAM,QAAQ,IAAI,OAAO,OAAO,IAAI,OAAO,SAAS,EAAE,GAAG,OAAO,IAAI,OAAO,SAAS,EAAE,CAAC;AAEvF,SAAO,QAAQ,iBAAiB,KAAK,KAAK;AAC1C,SAAO,SAAS,eAAe,IAAI,GAAG,CAAC;AACvC,SAAO,WAAW;AAClB,SAAO,aAAa;AACpB,SAAO,MAAM;AAEb,SAAO;AACX;AAaA,IAAM,mBAAmB;AAAA,EACrB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAClB;AAEA,IAAM,uBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,aAAa,IAAI,OAAO;AAC7B,SAAK,OAAO,IAAI,OAAO;AACvB,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,SAAS,yBAAyB,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAChF;AACI,QAAM,IAAI,IAAI,qBAAqB;AACnC,IAAE,SAAS;AACX,IAAE,SAAS;AACX,QAAM,QAAQ,MAAM;AACpB,UAAQ,OAAO,IAAI,SAAS,QAAQ,CAAC;AAErC,IAAE,SAAS,IAAI,QAAQ;AACvB,SAAO,OAAO,EAAE,QAAQ,MAAM;AAC9B,IAAE,SAAS,IAAI,QAAQ;AACvB,SAAO,OAAO,EAAE,QAAQ,MAAM;AAC9B,IAAE,aAAa,IAAI,OAAO;AAC1B,IAAE,OAAO,IAAI,OAAO;AACpB,IAAE,OAAO;AAET,QAAM,MAAM,oBAAoB,QAAQ,EAAE;AAC1C,QAAM,MAAM,oBAAoB,QAAQ,EAAE;AAE1C,MAAI,UAAU,GACd;AACI,MAAE,OAAO,iBAAiB;AAC1B,UAAM,cAAc,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AACjD,UAAMC,eAAc,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AACjD,UAAMC,UAAS,iBAAiB,KAAK,WAAW;AAChD,UAAMC,UAAS,iBAAiB,KAAKF,YAAW;AAChD,MAAE,OAAO,YAAY,MAAME,SAAQD,OAAM,CAAC;AAC1C,MAAE,aAAa,IAAI,OAAO;AAE1B,WAAO;AAAA,EACX;AAEA,MAAI,MAAM,OAAO,CAAC,MAAM,MAAM,OAAO,CAAC,GACtC;AAEI,MAAE,OAAO,iBAAiB;AAC1B,UAAM,eAAe,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AAClD,UAAM,eAAe,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AAElD,MAAE,OAAO,UAAU,MAAM,cAAc,YAAY,GAAG,CAAG;AACzD,MAAE,OAAO,YAAY,EAAE,IAAI;AAC3B,UAAME,UAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAE3C,MAAE,aAAa,IAAI,OAAO,OAAO,aAAa,IAAI,aAAa,IAAI,OAAO,aAAa,IAAI,aAAa,EAAE;AAC1G,UAAMD,UAAS,iBAAiB,KAAK,EAAE,UAAU;AAEjD,UAAM,cAAc,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AACjD,UAAMD,UAAS,iBAAiB,KAAK,WAAW;AAEhD,UAAMG,KAAI,MAAM,MAAMH,SAAQC,OAAM,GAAGC,OAAM;AAE7C,QAAIC,KAAI,GACR;AACI,QAAE,OAAO,MAAM,EAAE,IAAI;AAAA,IACzB;AAEA,WAAO;AAAA,EACX;AAGA,IAAE,OAAO,iBAAiB;AAC1B,QAAM,eAAe,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AAClD,QAAM,eAAe,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AAElD,IAAE,OAAO,UAAU,MAAM,cAAc,YAAY,GAAG,CAAG;AACzD,IAAE,OAAO,YAAY,EAAE,IAAI;AAC3B,QAAM,SAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAE3C,IAAE,aAAa,IAAI,OAAO,OAAO,aAAa,IAAI,aAAa,IAAI,OAAO,aAAa,IAAI,aAAa,EAAE;AAC1G,QAAM,SAAS,iBAAiB,KAAK,EAAE,UAAU;AAEjD,QAAM,cAAc,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC;AACjD,QAAM,SAAS,iBAAiB,KAAK,WAAW;AAEhD,QAAM,IAAI,MAAM,MAAM,QAAQ,MAAM,GAAG,MAAM;AAE7C,MAAI,IAAI,GACR;AACI,MAAE,OAAO,MAAM,EAAE,IAAI;AAAA,EACzB;AAEA,SAAO;AACX;AAEA,IAAM,sBAAN,MACA;AAAA,EACI,YAAY,QAAQ,QAAQ,YAC5B;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,aAAa;AAAA,EAEtB;AACJ;AAEO,SAAS,oBAAoB,GAAG,GACvC;AACI,QAAM,MAAM,oBAAoB,EAAE,QAAQ,CAAC;AAC3C,QAAM,MAAM,oBAAoB,EAAE,QAAQ,CAAC;AAE3C,UAAQ,EAAE,MACV;AAAA,IACI,KAAK,iBAAiB,eACtB;AACI,YAAM,QAAQ,kBAAkB,IAAI,GAAG,EAAE,IAAI;AAC7C,YAAM,QAAQ,kBAAkB,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;AAEpD,YAAM,SAAS,cAAc,EAAE,QAAQ,KAAK;AAC5C,YAAM,SAAS,cAAc,EAAE,QAAQ,KAAK;AAE5C,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAE1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAChD,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAEhD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,IAAI;AAEtD,aAAO,IAAI,oBAAoB,QAAQ,QAAQ,UAAU;AAAA,IAC7D;AAAA,IAEA,KAAK,iBAAiB,cACtB;AACI,YAAM,SAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAC3C,YAAM,SAAS,iBAAiB,KAAK,EAAE,UAAU;AAEjD,YAAM,QAAQ,kBAAkB,IAAI,GAAG,MAAM,MAAM,CAAC;AAEpD,YAAM,SAAS;AACf,YAAM,SAAS,cAAc,EAAE,QAAQ,KAAK;AAE5C,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAEhD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,MAAM;AAEtD,aAAO,IAAI,oBAAoB,QAAQ,QAAQ,UAAU;AAAA,IAC7D;AAAA,IAEA,KAAK,iBAAiB,cACtB;AACI,YAAM,SAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAC3C,YAAM,SAAS,iBAAiB,KAAK,EAAE,UAAU;AAEjD,YAAM,QAAQ,kBAAkB,IAAI,GAAG,MAAM,MAAM,CAAC;AAEpD,YAAM,SAAS;AACf,YAAM,SAAS,cAAc,EAAE,QAAQ,KAAK;AAE5C,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAEhD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,MAAM;AAEtD,aAAO,IAAI,oBAAoB,QAAQ,QAAQ,UAAU;AAAA,IAC7D;AAAA,IAEA;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,oBAAoB,IAAI,IAAI,CAAG;AAAA,EAClD;AACJ;AAEO,SAAS,qBAAqB,GAAG,QAAQ,QAAQ,GACxD;AACI,QAAM,MAAM,oBAAoB,EAAE,QAAQ,CAAC;AAC3C,QAAM,MAAM,oBAAoB,EAAE,QAAQ,CAAC;AAE3C,UAAQ,EAAE,MACV;AAAA,IACI,KAAK,iBAAiB,eACtB;AACI,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAChD,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAChD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,IAAI;AAEtD,aAAO;AAAA,IACX;AAAA,IAEA,KAAK,iBAAiB,cACtB;AACI,YAAM,SAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAC3C,YAAM,SAAS,iBAAiB,KAAK,EAAE,UAAU;AACjD,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAChD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,MAAM;AAEtD,aAAO;AAAA,IACX;AAAA,IAEA,KAAK,iBAAiB,cACtB;AACI,YAAM,SAAS,eAAe,IAAI,GAAG,EAAE,IAAI;AAC3C,YAAM,SAAS,iBAAiB,KAAK,EAAE,UAAU;AACjD,YAAM,cAAc,EAAE,OAAO,OAAO,MAAM;AAC1C,YAAM,SAAS,iBAAiB,KAAK,WAAW;AAChD,YAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,GAAG,MAAM;AAEtD,aAAO;AAAA,IACX;AAAA,IAEA;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO;AAAA,EACf;AACJ;AAoBO,SAAS,eAAe,OAC/B;AACI,QAAM,SAAS,IAAI,YAAY;AAC/B,SAAO,QAAQ,WAAW;AAC1B,SAAO,IAAI,MAAM;AAEjB,QAAM,SAAS,MAAM;AACrB,QAAM,SAAS,MAAM;AAErB,QAAM,SAAS,MAAM;AACrB,QAAM,SAAS,MAAM;AACrB,UAAQ,OAAQ,eAAgB,OAAO,EAAG,KAAK,eAAgB,OAAO,EAAG,GAAG,4BAA4B,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,CAAC,OAAO,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,CAAC,EAAG;AAChN,UAAQ,OAAQ,eAAgB,OAAO,EAAG,KAAK,eAAgB,OAAO,EAAG,GAAG,4BAA4B,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,CAAC,OAAO,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,IAAE,OAAO,GAAG,CAAC,EAAG;AAEhN,QAAM,OAAO,MAAM;AAEnB,QAAM,cAAc,OAAO,SAAS,OAAO;AAC3C,QAAM,SAAS,KAAK,IAAI,eAAe,cAAc,aAAa;AAClE,QAAM,YAAY,OAAO;AACzB,UAAQ,OAAQ,SAAS,SAAU;AAEnC,MAAI,KAAK;AACT,QAAM,kBAAkB;AACxB,MAAI,OAAO;AAGX,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,gBAAc,SAAS,MAAM;AAC7B,gBAAc,SAAS,MAAM;AAC7B,gBAAc,WAAW;AAIzB,aACA;AACI,UAAM,MAAM,oBAAoB,QAAQ,EAAE;AAC1C,UAAM,MAAM,oBAAoB,QAAQ,EAAE;AAI1C,kBAAc,aAAa;AAC3B,kBAAc,aAAa;AAC3B,UAAM,iBAAiB,gBAAgB,OAAO,eAAe,MAAM,CAAC;AAGpE,QAAI,eAAe,YAAY,GAC/B;AAGI,aAAO,QAAQ,WAAW;AAC1B,aAAO,IAAI;AAEX;AAAA,IACJ;AAEA,QAAI,eAAe,WAAW,SAAS,WACvC;AAEI,aAAO,QAAQ,WAAW;AAC1B,aAAO,IAAI;AAEX;AAAA,IACJ;AAGA,UAAM,MAAM,yBAAyB,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAI9E,QAAI,OAAO;AACX,QAAI,KAAK;AACT,QAAI,eAAe;AAEnB,eACA;AAEI,YAAM,MAAM,oBAAoB,KAAK,EAAE;AACvC,UAAI,KAAK,IAAI;AACb,YAAM,SAAS,IAAI;AACnB,YAAM,SAAS,IAAI;AAGnB,UAAI,KAAK,SAAS,WAClB;AAEI,eAAO,QAAQ,WAAW;AAC1B,eAAO,IAAI;AACX,eAAO;AAEP;AAAA,MACJ;AAGA,UAAI,KAAK,SAAS,WAClB;AAEI,aAAK;AAEL;AAAA,MACJ;AAGA,UAAI,KAAK,qBAAqB,KAAK,QAAQ,QAAQ,EAAE;AAIrD,UAAI,KAAK,SAAS,WAClB;AACI,eAAO,QAAQ,WAAW;AAC1B,eAAO,IAAI;AACX,eAAO;AAEP;AAAA,MACJ;AAGA,UAAI,MAAM,SAAS,WACnB;AAEI,eAAO,QAAQ,WAAW;AAC1B,eAAO,IAAI;AACX,eAAO;AAEP;AAAA,MACJ;AAGA,UAAI,gBAAgB;AACpB,UAAI,KAAK,IACL,KAAK;AAET,iBACA;AAEI,YAAI;AAEJ,YAAI,gBAAgB,GACpB;AAEI,cAAI,MAAM,SAAS,OAAO,KAAK,OAAO,KAAK;AAAA,QAC/C,OAEA;AAEI,cAAI,OAAO,KAAK;AAAA,QACpB;AAEA,UAAE;AAEF,cAAM,IAAI,qBAAqB,KAAK,QAAQ,QAAQ,CAAC;AAErD,YAAI,KAAK,IAAI,IAAI,MAAM,IAAI,WAC3B;AAEI,eAAK;AAEL;AAAA,QACJ;AAGA,YAAI,IAAI,QACR;AACI,eAAK;AACL,eAAK;AAAA,QACT,OAEA;AACI,eAAK;AACL,eAAK;AAAA,QACT;AAEA,YAAI,iBAAiB,IACrB;AACI;AAAA,QACJ;AAAA,MACJ;AAEA,QAAE;AAEF,UAAI,gBAAgB,yBACpB;AACI;AAAA,MACJ;AAAA,IACJ;AAEA,MAAE;AAEF,QAAI,MACJ;AACI;AAAA,IACJ;AAEA,QAAI,QAAQ,iBACZ;AAEI,aAAO,QAAQ,WAAW;AAC1B,aAAO,IAAI;AAEX;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AACX;;;ACzwCA,SAAS,cAAcC,KAAIC,KAAI,IAAI,OACnC;AACI,QAAM,OAAO,IAAI,OAAO;AAExB,MAAI,UAAU,GACd;AACI,WAAO;AAAA,EACX;AAGA,QAAM,IAAI,YAAY,MAAMA,KAAID,GAAE,CAAC;AAGnC,QAAM,cAAc,CAAC;AACrB,MAAI,aAAa;AAEjB,MAAI,YAAY;AAChB,MAAI,eAAe,QAAQ,MAAM,GAAG,SAAS,GAAGA,GAAE,GAAG,CAAC;AAEtD,MAAI,eAAe,GACnB;AACI,gBAAY,YAAY,IAAI,GAAG,SAAS;AAAA,EAC5C;AAEA,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAM,WAAW,QAAQ,MAAM,GAAG,CAAC,GAAGA,GAAE,GAAG,CAAC;AAE5C,QAAI,WAAW,cACf;AACI,kBAAY;AACZ,qBAAe;AAAA,IACnB;AAEA,QAAI,WAAW,GACf;AACI,kBAAY,YAAY,IAAI,GAAG,CAAC;AAAA,IACpC;AAAA,EACJ;AAEA,MAAI,eAAe,IAAM,eACzB;AACI,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,GAAG,SAAS;AAG9B,QAAM,QAAQ,cAAcA,KAAI,WAAW,aAAa,UAAU;AAGlE,QAAM,QAAQ,cAAc,WAAWC,KAAI,aAAa,UAAU;AAGlE,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,SAAK,OAAO,KAAK,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,EAC9C;AAEA,OAAK,OAAO,KAAK,OAAO,IAAI;AAE5B,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,SAAK,OAAO,KAAK,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,EAC9C;AAEA,SAAO;AACX;AAEO,SAAS,eAAe,QAAQ,OACvC;AACI,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,OAAO,KAC3B;AACI,UAAM,KAAK,IAAI,KAAK;AACpB,aAAS,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE;AAAA,EACnE;AAEA,SAAO,OAAO;AAClB;AAgCO,SAAS,cAAc,QAAQ,OACtC;AACI,QAAM,OAAO,IAAI,OAAO;AAExB,MAAI,QAAQ,KAAK,QAAQ,yBACzB;AAEI,YAAQ,OAAO,OAAO,yCAAyC;AAE/D,WAAO;AAAA,EACX;AAIA,QAAM,OAAO,IAAI,OAAO,OAAO,WAAW,OAAO,WAAW,CAAC,OAAO,WAAW,CAAC,OAAO,SAAS;AAIhG,QAAM,KAAK,CAAC;AACZ,MAAI,IAAI;AACR,QAAM,SAAS,KAAO,gBAAgB;AAEtC,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AAEI,SAAK,cAAc,KAAK,IAAI,KAAK,aAAa,OAAO,CAAC,EAAE,CAAC;AACzD,SAAK,cAAc,KAAK,IAAI,KAAK,aAAa,OAAO,CAAC,EAAE,CAAC;AAGzD,SAAK,cAAc,KAAK,IAAI,KAAK,aAAa,OAAO,CAAC,EAAE,CAAC;AACzD,SAAK,cAAc,KAAK,IAAI,KAAK,aAAa,OAAO,CAAC,EAAE,CAAC;AAEzD,UAAM,KAAK,OAAO,CAAC;AAEnB,QAAI,SAAS;AAEb,aAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GACzB;AACI,YAAM,KAAK,OAAO,CAAC;AAEnB,YAAM,UAAU,kBAAkB,IAAI,EAAE;AAExC,UAAI,UAAU,QACd;AACI,iBAAS;AAET;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,QACJ;AACI,SAAG,GAAG,IAAI;AAAA,IACd;AAAA,EACJ;AAEA,MAAI,IAAI,GACR;AAEI,WAAO;AAAA,EACX;AAGA,QAAMC,KAAI,cAAc,IAAI;AAC5B,MAAI,KAAK;AACT,MAAI,OAAO,kBAAkBA,IAAG,GAAG,EAAE,CAAC;AAEtC,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GACzB;AACI,UAAM,MAAM,kBAAkBA,IAAG,GAAG,CAAC,CAAC;AAEtC,QAAI,MAAM,MACV;AACI,WAAK;AACL,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,QAAMC,MAAK,GAAG,EAAE;AAChB,KAAG,EAAE,IAAI,GAAG,IAAI,CAAC;AACjB,MAAI,IAAI;AAER,MAAI,KAAK;AACT,MAAI,OAAO,kBAAkBA,KAAI,GAAG,EAAE,CAAC;AAEvC,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GACzB;AACI,UAAM,MAAM,kBAAkBA,KAAI,GAAG,CAAC,CAAC;AAEvC,QAAI,MAAM,MACV;AACI,WAAK;AACL,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,QAAMC,MAAK,GAAG,EAAE;AAChB,KAAG,EAAE,IAAI,GAAG,IAAI,CAAC;AACjB,MAAI,IAAI;AAGR,QAAM,cAAc,CAAC;AACrB,MAAI,aAAa;AAEjB,QAAM,aAAa,CAAC;AACpB,MAAI,YAAY;AAEhB,QAAM,IAAI,YAAY,MAAMA,KAAID,GAAE,CAAC;AAEnC,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GACzB;AACI,UAAM,IAAI,QAAQ,MAAM,GAAG,CAAC,GAAGA,GAAE,GAAG,CAAC;AAGrC,QAAI,KAAK,IAAM,eACf;AACI,kBAAY,YAAY,IAAI,GAAG,CAAC;AAAA,IACpC,WACS,KAAK,KAAO,eACrB;AACI,iBAAW,WAAW,IAAI,GAAG,CAAC;AAAA,IAClC;AAAA,EACJ;AAGA,QAAM,QAAQ,cAAcA,KAAIC,KAAI,aAAa,UAAU;AAC3D,QAAM,QAAQ,cAAcA,KAAID,KAAI,YAAY,SAAS;AAEzD,MAAI,MAAM,UAAU,KAAK,MAAM,UAAU,GACzC;AAEI,WAAO;AAAA,EACX;AAGA,OAAK,OAAO,KAAK,OAAO,IAAIA;AAE5B,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,SAAK,OAAO,KAAK,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,EAC9C;AAEA,OAAK,OAAO,KAAK,OAAO,IAAIC;AAE5B,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,SAAK,OAAO,KAAK,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,EAC9C;AAEA,UAAQ,OAAO,KAAK,SAAS,uBAAuB;AAGpD,MAAI,YAAY;AAEhB,SAAO,aAAa,KAAK,QAAQ,GACjC;AACI,gBAAY;AAEZ,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE,GAClC;AACI,YAAM,KAAK;AACX,YAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,YAAM,MAAM,IAAI,KAAK,KAAK;AAE1B,YAAM,KAAK,KAAK,OAAO,EAAE;AACzB,YAAM,KAAK,KAAK,OAAO,EAAE;AACzB,YAAM,KAAK,KAAK,OAAO,EAAE;AAGzB,YAAM,IAAI,YAAY,MAAM,IAAI,EAAE,CAAC;AAEnC,YAAM,WAAW,QAAQ,MAAM,IAAI,EAAE,GAAG,CAAC;AAEzC,UAAI,YAAY,IAAM,eACtB;AAEI,iBAAS,IAAI,IAAI,IAAI,KAAK,QAAQ,GAAG,EAAE,GACvC;AACI,eAAK,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC;AAAA,QACtC;AACA,aAAK,SAAS;AAGd,oBAAY;AAEZ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,KAAK,QAAQ,GACjB;AAEI,SAAK,QAAQ;AAAA,EACjB;AAEA,SAAO;AACX;AAcO,SAAS,eAAe,MAC/B;AACI,MAAI,CAAC,cACL;AACI,WAAO;AAAA,EACX;AAEA,MAAI,KAAK,QAAQ,KAAK,0BAA0B,KAAK,OACrD;AACI,YAAQ,KAAK,4CAA4C;AAEzD,WAAO;AAAA,EACX;AAGA,MAAI,CAAC,eAAe,KAAK,QAAQ,KAAK,KAAK,GAC3C;AACI,YAAQ,KAAK,0CAA0C;AAEvD,WAAO;AAAA,EACX;AAGA,WAAS,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE,GAClC;AAEI,UAAM,KAAK;AACX,UAAM,KAAK,IAAI,KAAK,QAAQ,IAAI,KAAK,IAAI;AACzC,UAAMC,KAAI,KAAK,OAAO,EAAE;AACxB,UAAM,IAAI,YAAY,MAAM,KAAK,OAAO,EAAE,GAAGA,EAAC,CAAC;AAE/C,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE,GAClC;AAEI,UAAI,MAAM,MAAM,MAAM,IACtB;AACI;AAAA,MACJ;AAEA,YAAM,WAAW,QAAQ,MAAM,KAAK,OAAO,CAAC,GAAGA,EAAC,GAAG,CAAC;AAEpD,UAAI,YAAY,GAChB;AACI,gBAAQ,KAAK,+CAA+C;AAE5D,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAGA,WAAS,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE,GAClC;AACI,UAAM,KAAK;AACX,UAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,UAAM,MAAM,IAAI,KAAK,KAAK;AAE1B,UAAMF,MAAK,KAAK,OAAO,EAAE;AACzB,UAAMC,MAAK,KAAK,OAAO,EAAE;AACzB,UAAME,MAAK,KAAK,OAAO,EAAE;AAEzB,UAAM,IAAI,YAAY,MAAMA,KAAIH,GAAE,CAAC;AAEnC,UAAM,WAAW,QAAQ,MAAMC,KAAID,GAAE,GAAG,CAAC;AAEzC,QAAI,YAAY,eAChB;AAEI,cAAQ,KAAK,qCAAqC;AAElD,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,SAAO;AACX;;;ACpWO,SAAS,aAAa,OAC7B;AACI,QAAM,UAAU,eAAe,MAAM,MAAM,KAAK,eAAe,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW,KAClG,KAAO,MAAM,eAAe,MAAM,cAAc;AAE9D,SAAO;AACX;AAEA,SAAS,yBAAyB,UAAU,OAC5C;AACI,MAAI,SAAS,IAAI,OAAO,GAAK,CAAG;AAChC,MAAI,OAAO;AAIX,QAAM,SAAS,SAAS,CAAC;AAEzB,QAAM,OAAO,IAAM;AAEnB,WAAS,IAAI,GAAG,IAAI,QAAQ,GAAG,EAAE,GACjC;AAEI,UAAM,KAAK,MAAM,SAAS,CAAC,GAAG,MAAM;AACpC,UAAM,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,MAAM;AACxC,UAAM,IAAI,MAAM,QAAQ,IAAI,EAAE;AAG9B,aAAS,SAAS,QAAQ,IAAI,MAAM,MAAM,IAAI,EAAE,CAAC;AACjD,YAAQ;AAAA,EACZ;AAGA,UAAQ,OAAO,OAAO,GAAG;AACzB,QAAM,UAAU,IAAM;AACtB,SAAO,KAAK;AACZ,SAAO,KAAK;AAGZ,WAAS,MAAM,QAAQ,MAAM;AAE7B,SAAO;AACX;AAgBO,SAAS,cAAc,MAAM,QAAQ,aAAa,MACzD;AACI,MAAI,cAAc,CAAC,eAAe,IAAI,GACtC;AACI,YAAQ,KAAK,eAAe;AAE5B,WAAO;AAAA,EACX;AAEA,MAAI,KAAK,QAAQ,GACjB;AAEI,WAAO,aAAa,GAAG;AAAA,EAC3B;AAEA,QAAM,QAAQ,IAAI,UAAU;AAC5B,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS;AAGf,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,UAAM,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC;AAAA,EACrC;AAGA,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,UAAM,KAAK;AACX,UAAM,KAAK,IAAI,IAAI,MAAM,QAAQ,IAAI,IAAI;AACzC,UAAM,OAAO,MAAM,MAAM,SAAS,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC;AACzD,YAAQ,OAAO,MAAM,MAAM,IAAI,IAAI,MAAM,GAAG;AAC5C,UAAM,QAAQ,CAAC,IAAI,YAAY,UAAU,MAAM,CAAG,CAAC;AAAA,EACvD;AAEA,QAAM,WAAW,yBAAyB,MAAM,UAAU,MAAM,KAAK;AAErE,SAAO;AACX;AAcO,SAAS,oBAAoB,MAAM,QAAQ,WAAW,aAAa,MAC1E;AACI,UAAQ,OAAO,cAAc,eAAe,IAAI,GAAG,eAAe;AAElE,MAAI,KAAK,QAAQ,GACjB;AAEI,WAAO,aAAa,GAAG;AAAA,EAC3B;AAEA,QAAM,QAAQ,IAAI,UAAU;AAC5B,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS;AAGf,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,UAAM,SAAS,CAAC,IAAI,iBAAiB,WAAW,KAAK,OAAO,CAAC,CAAC;AAAA,EAClE;AAGA,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,UAAM,KAAK;AACX,UAAM,KAAK,IAAI,IAAI,MAAM,QAAQ,IAAI,IAAI;AACzC,UAAM,OAAO,MAAM,MAAM,SAAS,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC;AACzD,YAAQ,OAAO,MAAM,MAAM,IAAI,IAAI,MAAM,GAAG;AAC5C,UAAM,QAAQ,CAAC,IAAI,YAAY,UAAU,MAAM,CAAG,CAAC;AAAA,EACvD;AAEA,QAAM,WAAW,yBAAyB,MAAM,UAAU,MAAM,KAAK;AAErE,SAAO;AACX;AAWO,SAAS,aAAa,GAC7B;AACI,SAAO,UAAU,GAAG,CAAC;AACzB;AAiBO,SAAS,UAAU,IAAI,IAC9B;AACI,UAAQ,OAAO,UAAU,EAAE,KAAK,KAAK,CAAG;AACxC,UAAQ,OAAO,UAAU,EAAE,KAAK,KAAK,CAAG;AAExC,QAAM,QAAQ,IAAI,UAAU;AAC5B,QAAM,QAAQ;AACd,QAAM,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;AACvC,QAAM,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE;AACtC,QAAM,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,EAAE;AACrC,QAAM,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;AACtC,QAAM,QAAQ,CAAC,IAAI,IAAI,OAAO,GAAK,EAAI;AACvC,QAAM,QAAQ,CAAC,IAAI,IAAI,OAAO,GAAK,CAAG;AACtC,QAAM,QAAQ,CAAC,IAAI,IAAI,OAAO,GAAK,CAAG;AACtC,QAAM,QAAQ,CAAC,IAAI,IAAI,OAAO,IAAM,CAAG;AACvC,QAAM,SAAS;AACf,QAAM,WAAW,IAAI,OAAO,GAAE,CAAC;AAE/B,SAAO;AACX;AAUO,SAAS,iBAAiB,IAAI,IAAI,QACzC;AACI,QAAM,QAAQ,UAAU,IAAI,EAAE;AAC9B,QAAM,SAAS;AAEf,SAAO;AACX;AAeO,SAAS,gBAAgB,IAAI,IAAI,QAAQ,QAAQ,GACxD;AACI,QAAMI,MAAK,IAAI,YAAY;AAC3B,EAAAA,IAAG,IAAI;AACP,EAAAA,IAAG,IAAI,UAAU,KAAK;AAEtB,QAAM,QAAQ,IAAI,UAAU;AAC5B,QAAM,QAAQ;AACd,QAAM,SAAS,CAAC,IAAI,iBAAiBA,KAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;AAC7D,QAAM,SAAS,CAAC,IAAI,iBAAiBA,KAAI,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;AAC5D,QAAM,SAAS,CAAC,IAAI,iBAAiBA,KAAI,IAAI,OAAO,IAAI,EAAE,CAAC;AAC3D,QAAM,SAAS,CAAC,IAAI,iBAAiBA,KAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;AAC5D,QAAM,QAAQ,CAAC,IAAI,eAAeA,IAAG,GAAG,IAAI,OAAO,GAAK,EAAI,CAAC;AAC7D,QAAM,QAAQ,CAAC,IAAI,eAAeA,IAAG,GAAG,IAAI,OAAO,GAAK,CAAG,CAAC;AAC5D,QAAM,QAAQ,CAAC,IAAI,eAAeA,IAAG,GAAG,IAAI,OAAO,GAAK,CAAG,CAAC;AAC5D,QAAM,QAAQ,CAAC,IAAI,eAAeA,IAAG,GAAG,IAAI,OAAO,IAAM,CAAG,CAAC;AAC7D,QAAM,SAAS;AACf,QAAM,WAAW;AAEjB,SAAO;AACX;AAcO,SAAS,mBAAmB,WAAW,SAC9C;AACI,QAAMC,KAAI;AAEV,WAAS,IAAI,GAAG,IAAIA,GAAE,OAAO,EAAE,GAC/B;AACI,IAAAA,GAAE,SAAS,CAAC,IAAI,iBAAiB,WAAWA,GAAE,SAAS,CAAC,CAAC;AACzD,IAAAA,GAAE,QAAQ,CAAC,IAAI,eAAe,UAAU,GAAGA,GAAE,QAAQ,CAAC,CAAC;AAAA,EAC3D;AAEA,EAAAA,GAAE,WAAW,iBAAiB,WAAWA,GAAE,QAAQ;AAEnD,SAAOA;AACX;AAgBO,SAAS,oBAAoB,OAAO,SAC3C;AACI,QAAM,KAAK,MAAM,SAAS,MAAM;AAEhC,QAAM,WAAW,IAAI,WAAW;AAChC,WAAS,OAAO,UAAU,KAAK,KAAK;AACpC,WAAS,SAAS,MAAM,OAAO,MAAM;AAGrC,WAAS,oBAAoB,SAAS,QAAQ,MAAM,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM;AAEzF,SAAO;AACX;AAcO,SAAS,qBAAqB,OAAO,SAC5C;AACI,QAAM,SAAS,MAAM;AACrB,QAAM,KAAK,SAAS;AACpB,QAAMC,MAAK,MAAM;AACjB,QAAMC,MAAK,MAAM;AACjB,QAAM,SAAS,SAAS,MAAMA,KAAID,GAAE,CAAC;AACrC,QAAM,KAAK,SAAS;AAEpB,QAAM,aAAa,UAAU,KAAK,KAAK;AACvC,QAAM,UAAU,WAAW,IAAM,SAAS;AAE1C,QAAM,WAAW,IAAI,WAAW;AAChC,WAAS,OAAO,aAAa;AAC7B,WAAS,SAAS,IAAI,OAAO,OAAOA,IAAG,IAAIC,IAAG,IAAI,OAAOD,IAAG,IAAIC,IAAG,EAAE;AAYrE,QAAM,KAAK,IAAM,UAAU,IAAM,KAAK;AAGtC,QAAM,IAAI,MAAM;AAEhB,QAAM,gBAAgB,cAAc,MAAM,KAAK,IAAI,IAAI,IAAM,IAAI;AACjE,QAAM,aAAa,WAAW,IAAM,KAAK,MAAM;AAC/C,WAAS,oBAAoB,gBAAgB;AAG7C,WAAS,qBAAqB,SAAS,OAAO,MAAM,SAAS,QAAQ,SAAS,MAAM;AAEpF,SAAO;AACX;AAgBO,SAAS,qBAAqB,OAAO,SAC5C;AACI,UAAQ,OAAO,MAAM,QAAQ,CAAC;AAE9B,MAAI,MAAM,SAAS,GACnB;AACI,UAAM,SAAS,IAAI,SAAS;AAC5B,WAAO,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM;AACxC,WAAO,SAAS,MAAM;AAEtB,WAAO,oBAAoB,QAAQ,OAAO;AAAA,EAC9C;AAEA,MAAI,MAAM,SAAS,GACnB;AACI,UAAM,UAAU,IAAI,UAAU;AAC9B,YAAQ,UAAU,MAAM,SAAS,CAAC,EAAE,MAAM;AAC1C,YAAQ,UAAU,MAAM,SAAS,CAAC,EAAE,MAAM;AAC1C,YAAQ,SAAS,MAAM;AAEvB,WAAO,qBAAqB,SAAS,OAAO;AAAA,EAChD;AAEA,QAAM,WAAW,IAAI,MAAM,uBAAuB;AAClD,QAAM,QAAQ,MAAM;AACpB,QAAM,SAAS,MAAM;AACrB,UAAQ,OAAO,SAAS,uBAAuB;AAE/C,MAAI,SAAS,GACb;AAEI,UAAM,QAAQ;AAEd,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,IAAI,KAAK,IAAI,QAAQ,IAAI,IAAI;AACnC,YAAM,KAAK,MAAM,QAAQ,CAAC;AAC1B,YAAM,KAAK,MAAM,QAAQ,CAAC;AAE1B,YAAM,MAAM,YAAY,MAAM,IAAI,EAAE,CAAC;AACrC,eAAS,CAAC,IAAI,SAAS,MAAM,SAAS,CAAC,GAAG,QAAQ,QAAQ,GAAG;AAAA,IACjE;AAAA,EACJ,OAEA;AACI,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,eAAS,CAAC,IAAI,MAAM,SAAS,CAAC;AAAA,IAClC;AAAA,EACJ;AAEA,MAAI,SAAS,IAAI,OAAO,GAAK,CAAG;AAChC,MAAI,OAAO;AACX,MAAI,oBAAoB;AAIxB,QAAM,IAAI,SAAS,CAAC;AAEpB,QAAM,OAAO,IAAM;AAEnB,WAAS,IAAI,GAAG,IAAI,QAAQ,GAAG,EAAE,GACjC;AAEI,UAAM,KAAK,MAAM,SAAS,CAAC,GAAG,CAAC;AAC/B,UAAM,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC;AAEnC,UAAM,IAAI,QAAQ,IAAI,EAAE;AAExB,UAAM,eAAe,MAAM;AAC3B,YAAQ;AAGR,aAAS,SAAS,QAAQ,eAAe,MAAM,MAAM,IAAI,EAAE,CAAC;AAE5D,UAAM,MAAM,GAAG,GACX,MAAM,GAAG;AACb,UAAM,MAAM,GAAG,GACX,MAAM,GAAG;AAEb,UAAM,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM;AAC5C,UAAM,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM;AAE5C,yBAAsB,OAAO,OAAO,KAAM,QAAQ;AAAA,EACtD;AAEA,QAAM,WAAW,IAAI,WAAW;AAGhC,WAAS,OAAO,UAAU;AAG1B,UAAQ,OAAO,OAAO,GAAG;AACzB,QAAM,UAAU,IAAM;AACtB,SAAO,KAAK;AACZ,SAAO,KAAK;AACZ,WAAS,SAAS,MAAM,GAAG,MAAM;AAGjC,WAAS,oBAAoB,UAAU;AAGvC,WAAS,qBAAqB,SAAS,QAAQ,MAAM,SAAS,QAAQ,SAAS,MAAM,IAAI,MAAM,QAAQ,MAAM;AAE7G,SAAO;AACX;AAYO,SAAS,oBAAoB,OAAOH,KAC3C;AAEI,QAAM,KAAMA,IAAG,EAAE,IAAI,MAAM,OAAO,IAAIA,IAAG,EAAE,IAAI,MAAM,OAAO,IAAKA,IAAG,EAAE;AACtE,QAAM,KAAMA,IAAG,EAAE,IAAI,MAAM,OAAO,IAAIA,IAAG,EAAE,IAAI,MAAM,OAAO,IAAKA,IAAG,EAAE;AACtE,QAAM,IAAI,MAAM;AAEhB,QAAM,OAAO,IAAI,OAAO,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEtD,SAAO;AACX;AAaO,SAAS,qBAAqB,OAAOA,KAC5C;AACI,QAAM,KAAK,iBAAiBA,KAAI,MAAM,OAAO;AAC7C,QAAM,KAAK,iBAAiBA,KAAI,MAAM,OAAO;AAE7C,QAAM,SAAS,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM;AAC5C,QAAM,SAAS,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM;AAC5C,QAAM,SAAS,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM;AAC5C,QAAM,SAAS,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM;AAE5C,QAAM,OAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,MAAM;AAEtD,SAAO;AACX;AAWO,SAAS,qBAAqB,OAAOA,KAC5C;AAEI,QAAM,KAAK,MAAM,SAAS,CAAC;AAC3B,MAAI,SAAUA,IAAG,EAAE,IAAI,GAAG,IAAIA,IAAG,EAAE,IAAI,GAAG,IAAKA,IAAG,EAAE;AACpD,MAAI,SAAUA,IAAG,EAAE,IAAI,GAAG,IAAIA,IAAG,EAAE,IAAI,GAAG,IAAKA,IAAG,EAAE;AACpD,MAAI,SAAS,QACT,SAAS;AAEb,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AAEI,UAAMI,MAAK,MAAM,SAAS,CAAC;AAC3B,UAAM,KAAMJ,IAAG,EAAE,IAAII,IAAG,IAAIJ,IAAG,EAAE,IAAII,IAAG,IAAKJ,IAAG,EAAE;AAClD,UAAM,KAAMA,IAAG,EAAE,IAAII,IAAG,IAAIJ,IAAG,EAAE,IAAII,IAAG,IAAKJ,IAAG,EAAE;AAGlD,aAAS,KAAK,IAAI,QAAQ,EAAE;AAC5B,aAAS,KAAK,IAAI,QAAQ,EAAE;AAG5B,aAAS,KAAK,IAAI,QAAQ,EAAE;AAC5B,aAAS,KAAK,IAAI,QAAQ,EAAE;AAAA,EAChC;AAEA,QAAM,IAAI,MAAM;AAGhB,YAAU;AACV,YAAU;AAGV,YAAU;AACV,YAAU;AAEV,QAAM,OAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,MAAM;AAEtD,SAAO;AACX;AAaO,SAAS,qBAAqB,OAAOA,KAC5C;AACI,QAAM,KAAK,iBAAiBA,KAAI,MAAM,MAAM;AAC5C,QAAM,KAAK,iBAAiBA,KAAI,MAAM,MAAM;AAE5C,QAAM,QAAQ,MAAM,IAAI,EAAE;AAC1B,QAAM,QAAQ,MAAM,IAAI,EAAE;AAE1B,QAAM,OAAO,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D,SAAO;AACX;AAYO,SAAS,gBAAgB,OAAO,OACvC;AACI,QAAM,SAAS,MAAM;AAErB,SAAO,kBAAkB,OAAO,MAAM,KAAK,MAAM,SAAS,MAAM;AACpE;AAeO,SAAS,iBAAiB,OAAO,OACxC;AACI,QAAM,KAAK,MAAM,SAAS,MAAM;AAChC,QAAME,MAAK,MAAM;AACjB,QAAMC,MAAK,MAAM;AAEjB,QAAM,IAAI,MAAMA,KAAID,GAAE;AACtB,QAAM,KAAK,MAAM,GAAG,CAAC;AAErB,MAAI,MAAM,GACV;AAEI,WAAO,kBAAkB,OAAOA,GAAE,KAAK;AAAA,EAC3C;AAOA,MAAI,IAAI,MAAM,MAAM,OAAOA,GAAE,GAAG,CAAC,IAAI;AACrC,MAAI,aAAa,GAAG,GAAK,CAAG;AAC5B,QAAMG,KAAI,SAASH,KAAI,GAAG,CAAC;AAG3B,SAAO,kBAAkB,OAAOG,EAAC,KAAK;AAC1C;AAWO,SAAS,iBAAiB,OAAO,OACxC;AACI,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,YAAY,MAAM,UAAU,MAAM,OAAO,CAAG;AAC3D,QAAM,SAAS,YAAY,CAAE,KAAM,GAAG,GAAG,CAAG;AAC5C,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,WAAW;AAEjB,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,SAAO,OAAO,YAAY,MAAM;AACpC;AAEA,IAAMC,YAAW,IAAI,OAAO,GAAG,CAAC;AAChC,IAAMC,aAAY,IAAI,OAAO,GAAG,CAAC;AAqB1B,SAAS,gBAAgB,OAAO,OACvC;AACI,UAAQ,OAAO,aAAa,KAAK,CAAC;AAElC,QAAMN,KAAI,MAAM,OAAO,MAAM;AAE7B,QAAM,SAAS,IAAI,aAAaM,YAAWD,SAAQ;AAGnD,QAAM,IAAI,MAAM,MAAM,QAAQL,EAAC;AAC/B,QAAM,MAAM,wBAAwB,MAAM,WAAW;AACrD,QAAM,SAAS,IAAI;AAEnB,MAAI,UAAU,GACd;AAEI,WAAO;AAAA,EACX;AACA,QAAM,IAAI,IAAI;AAKd,QAAM,IAAI,CAAC,MAAM,GAAG,CAAC;AAGrB,QAAMI,KAAI,SAAS,GAAG,GAAG,CAAC;AAE1B,QAAM,KAAK,MAAMA,IAAGA,EAAC;AACrB,QAAM,IAAI,MAAM;AAChB,QAAM,KAAK,IAAI;AAEf,MAAI,KAAK,IACT;AAEI,WAAO;AAAA,EACX;AAGA,QAAM,IAAI,KAAK,KAAK,KAAK,EAAE;AAE3B,QAAM,WAAW,IAAI;AAErB,MAAI,WAAW,KAAO,MAAM,cAAc,SAAS,UACnD;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,WAAW,SAAS,GAAG,UAAU,CAAC;AAExC,SAAO,WAAW,WAAW;AAC7B,SAAO,SAAS,YAAY,QAAQ;AACpC,SAAO,QAAQ,SAASJ,IAAG,MAAM,QAAQ,OAAO,MAAM;AACtD,SAAO,MAAM;AAEb,SAAO;AACX;AAqBO,SAAS,iBAAiB,OAAO,OACxC;AACI,UAAQ,OAAO,aAAa,KAAK,CAAC;AAElC,QAAM,SAAS,IAAI,aAAaM,YAAWD,SAAQ;AAEnD,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AAEjB,QAAM,IAAI,MAAM,IAAI,EAAE;AAEtB,QAAM,MAAM,wBAAwB,CAAC;AACrC,QAAM,gBAAgB,IAAI;AAC1B,QAAM,IAAI,IAAI;AAEd,MAAI,gBAAgB,KACpB;AAEI,UAAM,SAAS,IAAI,SAAS;AAC5B,WAAO,SAAS;AAChB,WAAO,SAAS,MAAM;AAEtB,WAAO,gBAAgB,OAAO,MAAM;AAAA,EACxC;AAEA,QAAMJ,MAAK,MAAM;AACjB,QAAM,IAAI,MAAM;AAGhB,QAAMM,KAAI,MAAMN,KAAI,EAAE;AACtB,QAAM,KAAK,MAAMM,IAAG,CAAC;AAGrB,QAAM,KAAK,SAASA,IAAG,CAAC,IAAI,CAAC;AAE7B,QAAM,SAAS,MAAM;AAGrB,MAAI,MAAM,IAAI,EAAE,IAAI,SAAS,QAC7B;AACI,QAAI,KAAK,GACT;AAEI,YAAM,SAAS,IAAI,SAAS;AAC5B,aAAO,SAAS;AAChB,aAAO,SAAS,MAAM;AAEtB,aAAO,gBAAgB,OAAO,MAAM;AAAA,IACxC;AAEA,QAAI,KAAK,GACT;AAEI,YAAM,SAAS,IAAI,SAAS;AAC5B,aAAO,SAAS;AAChB,aAAO,SAAS,MAAM;AAEtB,aAAO,gBAAgB,OAAO,MAAM;AAAA,IACxC;AAGA,WAAO;AAAA,EACX;AAGA,MAAI,IAAI,IAAI,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;AAE5B,QAAM,OAAO,wBAAwB,CAAC;AACtC,QAAM,YAAY,KAAK;AACvB,QAAM,IAAI,KAAK;AAYf,QAAM,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAEjC,MAAI,CAAC,MAAM,OAAO,MAAM,KACxB;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,KAAK,SAASA,IAAG,QAAQ,CAAC;AAChC,QAAM,KAAK,SAASA,IAAG,QAAQ,CAAC;AAEhC,QAAM,SAAS,IAAM;AAGrB,QAAM,OAAO,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,KAAK;AAGxC,QAAM,OAAO,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,KAAK;AAExC,MAAI,IAAI;AAER,MAAI,MAAM,KACV;AACI,SAAK;AACL,QAAI;AAAA,EACR,OAEA;AACI,SAAK;AACL,QAAI;AACJ,QAAI,MAAM,CAAC;AAAA,EACf;AAEA,MAAI,KAAK,KAAO,MAAM,cAAc,YAAY,IAChD;AACI,WAAO;AAAA,EACX;AAGA,QAAM,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAEtC,MAAI,KAAK,GACT;AAEI,UAAM,SAAS,IAAI,SAAS;AAC5B,WAAO,SAAS;AAChB,WAAO,SAAS,MAAM;AAEtB,WAAO,gBAAgB,OAAO,MAAM;AAAA,EACxC,WACS,gBAAgB,IACzB;AAEI,UAAM,SAAS,IAAI,SAAS;AAC5B,WAAO,SAAS;AAChB,WAAO,SAAS,MAAM;AAEtB,WAAO,gBAAgB,OAAO,MAAM;AAAA,EACxC,OAEA;AAEI,WAAO,WAAW,KAAK;AACvB,WAAO,QAAQ,MAAM,OAAO,IAAI,IAAI,KAAK,aAAa,GAAG,QAAQ,MAAM,QAAQ,CAAC,CAAC;AACjF,WAAO,SAAS;AAChB,WAAO,MAAM;AAEb,WAAO;AAAA,EACX;AACJ;AAYO,SAAS,iBAAiB,OAAO,OAAO,UAC/C;AACI,MAAI,UACJ;AAEI,UAAM,SAAS,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,MAAM,QAAQ,MAAM,MAAM,CAAC;AAE3F,QAAI,SAAS,GACb;AACI,YAAMC,UAAS,IAAI,aAAaF,YAAWD,SAAQ;AAEnD,aAAOG;AAAA,IACX;AAAA,EACJ;AAGA,QAAMP,MAAK,MAAM;AACjB,QAAM,IAAI,MAAM;AAEhB,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AACjB,QAAM,IAAI,MAAM,IAAI,EAAE;AAEtB,QAAM,SAAS,IAAI,aAAaK,YAAWD,SAAQ;AAEnD,QAAM,MAAM,wBAAwB,CAAC;AACrC,QAAM,SAAS,IAAI;AACnB,QAAM,QAAQ,IAAI;AAElB,MAAI,UAAU,GACd;AACI,WAAO;AAAA,EACX;AAGA,MAAI,SAAS,YAAY,KAAK;AAO9B,QAAM,YAAY,MAAM,QAAQ,MAAM,IAAIJ,GAAE,CAAC;AAC7C,QAAM,cAAc,MAAM,QAAQ,CAAC;AAEnC,MAAI,eAAe,GACnB;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,IAAI,YAAY;AAEtB,MAAI,IAAI,KAAO,MAAM,cAAc,GACnC;AAEI,WAAO;AAAA,EACX;AAGA,QAAMD,KAAI,SAASC,KAAI,GAAG,CAAC;AAM3B,QAAM,IAAI,MAAM,MAAMD,IAAG,EAAE,GAAG,KAAK;AAEnC,MAAI,IAAI,KAAO,SAAS,GACxB;AAEI,WAAO;AAAA,EACX;AAEA,MAAI,YAAY,GAChB;AACI,aAAS,MAAM,MAAM;AAAA,EACzB;AAEA,SAAO,WAAW;AAClB,SAAO,QAAQ,SAASC,KAAI,GAAG,CAAC;AAChC,SAAO,SAAS;AAChB,SAAO,MAAM;AAEb,SAAO;AACX;AAgBO,SAAS,iBAAiB,OAAO,OACxC;AACI,UAAQ,OAAO,aAAa,KAAK,CAAC;AAElC,MAAI,MAAM,WAAW,GACrB;AAEI,UAAMA,MAAK,MAAM;AACjB,UAAM,IAAI,MAAM;AAEhB,QAAI,QAAQ,GACR,QAAQ,MAAM;AAElB,QAAI,QAAQ;AAEZ,UAAM,SAAS,IAAI,aAAaK,YAAWD,SAAQ;AAEnD,aAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AAII,YAAM,YAAY,MAAM,MAAM,QAAQ,CAAC,GAAG,MAAM,MAAM,SAAS,CAAC,GAAGJ,GAAE,CAAC;AACtE,YAAM,cAAc,MAAM,MAAM,QAAQ,CAAC,GAAG,CAAC;AAE7C,UAAI,gBAAgB,GACpB;AACI,YAAI,YAAY,GAChB;AACI,iBAAO;AAAA,QACX;AAAA,MACJ,OAEA;AAKI,YAAI,cAAc,KAAO,YAAY,QAAQ,aAC7C;AAGI,kBAAQ,YAAY;AACpB,kBAAQ;AAAA,QACZ,WACS,cAAc,KAAO,YAAY,QAAQ,aAClD;AAGI,kBAAQ,YAAY;AAAA,QACxB;AAAA,MACJ;AAEA,UAAI,QAAQ,OACZ;AACI,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,YAAQ,OAAO,KAAO,SAAS,SAAS,MAAM,WAAW;AAEzD,QAAI,SAAS,GACb;AACI,aAAO,WAAW;AAClB,aAAO,SAAS,MAAM,QAAQ,KAAK;AACnC,aAAO,QAAQ,SAASA,KAAI,OAAO,CAAC;AACpC,aAAO,MAAM;AAAA,IACjB;AAEA,WAAO;AAAA,EACX;AAGA,QAAM,YAAY,IAAI,qBAAqB;AAC3C,YAAU,SAAS,YAAY,MAAM,UAAU,MAAM,OAAO,MAAM,MAAM;AACxE,YAAU,SAAS,YAAY,CAAE,MAAM,MAAO,GAAG,GAAG,CAAG;AACvD,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,eAAe,MAAM;AAC/B,YAAU,cAAc,MAAM;AAE9B,SAAO,YAAY,SAAS;AAChC;AAUO,SAAS,kBAAkB,OAAO,OACzC;AACI,QAAM,YAAY,IAAI,qBAAqB;AAC3C,YAAU,SAAS,YAAY,CAAE,MAAM,OAAO,MAAM,CAAE,GAAG,GAAG,MAAM,MAAM;AACxE,YAAU,SAAS,YAAY,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM;AACtE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,eAAe,MAAM;AAC/B,YAAU,cAAc,MAAM;AAE9B,QAAM,SAAS,YAAY,SAAS;AAEpC,SAAO;AACX;AAWO,SAAS,mBAAmB,OAAO,OAC1C;AACI,QAAM,YAAY,IAAI,qBAAqB;AAC3C,YAAU,SAAS,YAAY,CAAE,MAAM,SAAS,MAAM,OAAQ,GAAG,GAAG,MAAM,MAAM;AAChF,YAAU,SAAS,YAAY,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM;AACtE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,eAAe,MAAM;AAC/B,YAAU,cAAc,MAAM;AAE9B,QAAM,SAAS,YAAY,SAAS;AAEpC,SAAO;AACX;AAYO,SAAS,mBAAmB,OAAO,OAC1C;AACI,QAAM,YAAY,IAAI,qBAAqB;AAC3C,YAAU,SAAS,YAAY,CAAE,MAAM,QAAQ,MAAM,MAAO,GAAG,GAAG,CAAG;AACrE,YAAU,SAAS,YAAY,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM;AACtE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,eAAe,MAAM;AAC/B,YAAU,cAAc,MAAM;AAE9B,QAAM,SAAS,YAAY,SAAS;AAEpC,SAAO;AACX;AAWO,SAAS,mBAAmB,OAAO,OAC1C;AACI,QAAM,YAAY,IAAI,qBAAqB;AAC3C,YAAU,SAAS,YAAY,MAAM,UAAU,MAAM,OAAO,MAAM,MAAM;AACxE,YAAU,SAAS,YAAY,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM;AACtE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACxE,YAAU,eAAe,MAAM;AAC/B,YAAU,cAAc,MAAM;AAE9B,QAAM,SAAS,YAAY,SAAS;AAEpC,SAAO;AACX;;;ACpsCA,SAAS,WAAW,OAAO,SAC3B;AACI,QAAM,KAAK,QAAQ,SAAS;AAG5B,QAAM,QAAQ,MAAM,WAAW,EAAE;AAEjC,SAAO;AACX;AAEO,SAAS,oBAAoB,OAAO,OAC3C;AACI,SAAO,mBAAmB,OAAO,MAAM,MAAM;AACjD;AAEA,SAAS,gBAAgB,OAAO,SAChC;AACI,QAAM,KAAK,QAAQ,SAAS;AAG5B,QAAM,QAAQ,MAAM,WAAW,EAAE;AAEjC,SAAO;AACX;AAEA,SAAS,mBAAmB,OAAO,WAAW,WAC9C;AACI,QAAM,sBAAsB;AAC5B,QAAM,aAAa;AAEnB,QAAM,OAAO,mBAAmB,OAAO,SAAS;AAChD,OAAK,eAAe;AACpB,OAAK,eAAe;AACpB,OAAK,eAAe;AACpB,OAAK,eAAe;AACpB,QAAM,OAAO;AAEb,QAAM,SAAS,aAAa,WAAW,gBAAgB,sBAAsB;AAC7E,QAAM,UAAU,IAAI;AAAA,IAAO,KAAK,cAAc;AAAA,IAAQ,KAAK,cAAc;AAAA,IACrE,KAAK,cAAc;AAAA,IAAQ,KAAK,cAAc;AAAA,EAAM;AACxD,QAAM,UAAU;AACpB;AAEA,SAAS,sBAAsB,OAAO,MAAM,WAAW,KAAK,UAAU,WACtE;AAKI,QAAM,UAAU,UAAU,MAAM,WAAW;AAE3C,MAAI,WAAW,MAAM,WAAW,QAChC;AACI,UAAM,WAAW,KAAK,IAAI,QAAQ,CAAC;AAAA,EACvC;AAKA,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,UAAQ,WACR;AAAA,IACI,KAAK,YAAY;AACb,YAAM,UAAU;AAEhB;AAAA,IAEJ,KAAK,YAAY;AACb,YAAM,SAAS;AAEf;AAAA,IAEJ,KAAK,YAAY;AACb,YAAM,UAAU;AAEhB;AAAA,IAEJ,KAAK,YAAY;AACb,YAAM,UAAU;AAEhB;AAAA,IAEJ,KAAK,YAAY;AACb,YAAM,eAAe;AAErB;AAAA,IAEJ;AAEI;AAAA,EACR;AAEA,QAAM,KAAK;AACX,QAAM,SAAS,KAAK;AACpB,QAAM,OAAO;AACb,QAAM,UAAU,IAAI;AACpB,QAAM,WAAW,IAAI;AACrB,QAAM,cAAc,IAAI;AACxB,QAAM,SAAS,IAAI;AACnB,QAAM,WAAW,IAAI;AACrB,QAAM,cAAc,IAAI;AACxB,QAAM,WAAW,IAAI;AACrB,QAAM,eAAe;AACrB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,sBAAsB,IAAI;AAChC,QAAM,kBAAkB,IAAI;AAC5B,QAAM,uBAAuB,IAAI;AACjC,QAAM,SAAS;AACf,QAAM,WAAW;AACjB,QAAM,gBAAgB,mBAAmB,KAAK;AAC9C,QAAM,OAAO,IAAI,OAAO;AACxB,QAAM,UAAU,IAAI,OAAO;AAC3B,QAAM,YAAY;AAElB,MAAI,KAAK,YAAY,UAAU,gBAC/B;AACI,UAAM,YAAY,KAAK;AACvB,uBAAmB,OAAO,MAAM,YAAY,WAAW,WAAW,IAAI,oBAAoB;AAAA,EAC9F;AAEA,MAAI,KAAK,eAAe,eACxB;AAEI,UAAM,YAAY,MAAM,WAAW,KAAK,WAAW;AACnD,cAAU,cAAc;AAAA,EAC5B;AAEA,QAAM,cAAc;AACpB,QAAM,cAAc,KAAK;AACzB,OAAK,cAAc;AACnB,OAAK,cAAc;AAEnB,uBAAqB,KAAK;AAE1B,SAAO;AACX;AAEO,SAAS,cAAc,QAAQ,KAAK,UAAU,WACrD;AAEI,UAAQ,OAAO,UAAU,IAAI,OAAO,KAAK,IAAI,WAAW,CAAG;AAC3D,UAAQ,OAAO,UAAU,IAAI,QAAQ,KAAK,IAAI,YAAY,CAAG;AAC7D,UAAQ,OAAO,UAAU,IAAI,WAAW,KAAK,IAAI,eAAe,CAAG;AAEnE,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI,WAAO,IAAI,UAAW,GAAG,GAAG,CAAE;AAAA,EAClC;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,QAAM,QAAQ,sBAAsB,OAAO,MAAM,WAAW,KAAK,UAAU,SAAS;AAEpF,MAAI,KAAK,mBAAmB,MAC5B;AACI,yBAAqB,OAAO,IAAI;AAAA,EACpC;AAEA,uBAAqB,KAAK;AAE1B,QAAM,KAAK,IAAI,UAAU,MAAM,KAAK,GAAG,OAAO,QAAQ,MAAM,QAAQ;AAEpE,SAAO;AACX;AAUO,SAAS,oBAAoB,QAAQ,KAAK,QACjD;AACI,SAAO,cAAc,QAAQ,KAAK,QAAQ,YAAY,cAAc;AACxE;AAcO,SAAS,qBAAqB,QAAQ,KAAK,SAClD;AACI,QAAM,YAAY,kBAAkB,QAAQ,SAAS,QAAQ,OAAO;AAEpE,MAAI,aAAa,gBAAgB,eACjC;AACI,UAAM,SAAS,IAAI,SAAS;AAC5B,WAAO,SAAS,OAAO,QAAQ,SAAS,QAAQ,SAAS,GAAG;AAC5D,WAAO,SAAS,QAAQ;AAExB,WAAO,cAAc,QAAQ,KAAK,QAAQ,YAAY,cAAc;AAAA,EACxE;AAEA,SAAO,cAAc,QAAQ,KAAK,SAAS,YAAY,eAAe;AAC1E;AAWO,SAAS,qBAAqB,QAAQ,KAAK,SAClD;AACI,UAAQ,OAAO,UAAU,QAAQ,MAAM,KAAK,QAAQ,UAAU,CAAG;AAEjE,SAAO,cAAc,QAAQ,KAAK,SAAS,YAAY,eAAe;AAC1E;AAgBO,SAAS,qBAAqB,QAAQ,KAAK,SAClD;AACI,QAAM,YAAY,kBAAkB,QAAQ,QAAQ,QAAQ,MAAM;AAElE,MAAI,aAAa,gBAAgB,eACjC;AACI,YAAQ,OAAO,KAAK;AAEpB,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,SAAO,cAAc,QAAQ,KAAK,SAAS,YAAY,eAAe;AAC1E;AAEA,SAAS,uBAAuB,OAAO,OAAO,MAAM,YACpD;AACI,QAAM,UAAU,MAAM;AAEtB,MAAI,MAAM,gBAAgB,eAC1B;AAEI,UAAM,WAAW,MAAM,WAAW,EAAE,cAAc,MAAM;AAAA,EAC5D;AAEA,MAAI,MAAM,gBAAgB,eAC1B;AAEI,UAAM,WAAW,MAAM,WAAW,EAAE,cAAc,MAAM;AAAA,EAC5D;AAEA,MAAI,YAAY,KAAK,aACrB;AACI,SAAK,cAAc,MAAM;AAAA,EAC7B;AAEA,OAAK,cAAc;AAEnB,sBAAoB,OAAO,MAAM,UAAU;AAE3C,MAAI,aAAa,KAAK;AAEtB,SAAO,eAAe,eACtB;AACI,UAAM,YAAY,cAAc;AAChC,UAAM,YAAY,aAAa;AAG/B,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,iBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,QAAI,QAAQ,aAAa,WAAW,QAAQ,aAAa,SACzD;AACI,uBAAiB,OAAO,SAAS,UAAU;AAAA,IAC/C;AAAA,EACJ;AAEA,WAAS,MAAM,aAAa,OAAO;AACnC,QAAM,KAAK;AAEX,uBAAqB,KAAK;AAC9B;AAcO,SAAS,eAAe,SAC/B;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,QAAM,KAAK,QAAQ,SAAS;AAI5B,QAAM,QAAQ,MAAM,WAAW,EAAE;AAEjC,QAAM,aAAa;AAEnB,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,yBAAuB,OAAO,OAAO,MAAM,UAAU;AAErD,MAAI,KAAK,mBAAmB,MAC5B;AACI,yBAAqB,OAAO,IAAI;AAAA,EACpC;AACJ;AAmBO,SAAS,cAAc,QAAQ,KACtC;AAEI,UAAQ,OAAO,UAAU,IAAI,QAAQ,KAAK,IAAI,YAAY,CAAG;AAC7D,UAAQ,OAAO,UAAU,IAAI,WAAW,KAAK,IAAI,eAAe,CAAG;AACnE,UAAQ,OAAO,IAAI,SAAS,CAAC;AAE7B,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,QAAM,UAAU,UAAU,MAAM,WAAW;AAE3C,MAAI,YAAY,MAAM,WAAW,QACjC;AACI,UAAM,WAAW,KAAK,IAAI,aAAa,CAAC;AAAA,EAC5C;AAGA,QAAM,aAAa,MAAM,WAAW,OAAO;AAE3C,aAAW,KAAK;AAChB,aAAW,SAAS,KAAK;AACzB,aAAW,cAAc,KAAK;AAC9B,aAAW,YAAY;AACvB,OAAK,cAAc;AAEnB,QAAM,WAAW,kBAAkB;AACnC,WAAS,WAAW,IAAI;AACxB,WAAS,cAAc,IAAI;AAC3B,WAAS,WAAW,IAAI;AACxB,WAAS,SAAS,IAAI;AACtB,WAAS,sBAAsB;AAC/B,WAAS,kBAAkB;AAC3B,WAAS,qBAAqB;AAE9B,QAAM,IAAI,IAAI;AACd,QAAM,SAAS,IAAI;AACnB,MAAI;AAEJ,MAAI,IAAI,QACR;AACI,eAAW,QAAQ;AACnB,eAAW,eAAe,IAAI,MAAM,CAAC;AAErC,QAAI,YAAY,IAAI;AAEpB,aAAS,IAAI,GAAG,IAAI,IAAI,GAAG,EAAE,GAC7B;AACI,qBAAe,IAAI,eAAe;AAClC,mBAAa,SAAS,OAAO,SAAS,EAAE,MAAM;AAC9C,mBAAa,UAAU,IAAI,UAAU;AACrC,mBAAa,QAAQ,SAAS,OAAO,CAAC,EAAE,MAAM;AAC9C,mBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,mBAAa,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAC1C,mBAAa,UAAU;AACvB,kBAAY;AAEZ,YAAMQ,SAAQ,sBAAsB,OAAO,MAAM,WAAW,UAAU,cAAc,YAAY,oBAAoB;AACpH,iBAAW,aAAa,CAAC,IAAIA,OAAM;AAAA,IACvC;AAEA,mBAAe,IAAI,eAAe;AAClC,iBAAa,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAC1C,iBAAa,UAAU,IAAI,UAAU;AACrC,iBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,iBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,iBAAa,SAAS,OAAO,CAAC,EAAE,MAAM;AACtC,iBAAa,UAAU;AACvB,QAAI,QAAQ,sBAAsB,OAAO,MAAM,WAAW,UAAU,cAAc,YAAY,oBAAoB;AAClH,eAAW,aAAa,IAAI,CAAC,IAAI,MAAM;AAEvC,mBAAe,IAAI,eAAe;AAClC,iBAAa,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAC1C,iBAAa,UAAU,IAAI,UAAU;AACrC,iBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,iBAAa,QAAQ,SAAS,OAAO,CAAC,EAAE,MAAM;AAC9C,iBAAa,SAAS,OAAO,CAAC,EAAE,MAAM;AACtC,iBAAa,UAAU;AACvB,YAAQ,sBAAsB,OAAO,MAAM,WAAW,UAAU,cAAc,YAAY,oBAAoB;AAC9G,eAAW,aAAa,IAAI,CAAC,IAAI,MAAM;AAAA,EAC3C,OAEA;AACI,eAAW,QAAQ,IAAI;AACvB,eAAW,eAAe,IAAI,MAAM,CAAC;AAErC,aAAS,IAAI,GAAG,IAAI,IAAI,GAAG,EAAE,GAC7B;AACI,qBAAe,IAAI,eAAe;AAClC,mBAAa,SAAS,OAAO,CAAC,EAAE,MAAM;AACtC,mBAAa,UAAU,IAAI,UAAU;AACrC,mBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,mBAAa,QAAQ,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAClD,mBAAa,SAAS,OAAO,IAAI,CAAC,EAAE,MAAM;AAC1C,mBAAa,UAAU;AAEvB,YAAM,QAAQ,sBAAsB,OAAO,MAAM,WAAW,UAAU,cAAc,YAAY,oBAAoB;AACpH,iBAAW,aAAa,CAAC,IAAI,MAAM;AAAA,IACvC;AAAA,EACJ;AAEA,QAAM,KAAK,IAAI,UAAU,UAAU,GAAG,MAAM,SAAS,WAAW,QAAQ;AAExE,SAAO;AACX;AAWO,SAAS,eAAe,SAC/B;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,QAAM,KAAK,QAAQ,SAAS;AAI5B,QAAM,QAAQ,MAAM,WAAW,EAAE;AACjC,QAAM,aAAa;AAEnB,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAG1C,MAAI,aAAa,KAAK;AACtB,MAAI,QAAQ;AAEZ,SAAO,eAAe,MACtB;AACI,QAAI,eAAe,MAAM,IACzB;AAEI,cAAQ;AAER;AAAA,IACJ;AAEA,iBAAa,MAAM,WAAW,UAAU,EAAE;AAAA,EAC9C;AAEA,UAAQ,OAAO,UAAU,IAAI;AAE7B,MAAI,UAAU,OACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,MAAM;AAEpB,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAM,UAAU,MAAM,aAAa,CAAC;AAGpC,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,2BAAuB,OAAO,OAAO,MAAM,UAAU;AAAA,EACzD;AAEA,QAAM,eAAe;AAGrB,WAAS,MAAM,aAAa,EAAE;AAC9B,QAAM,KAAK;AAEX,uBAAqB,KAAK;AAC9B;AAEO,SAAS,mBAAmB,OAAOC,KAC1C;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,SAASA,GAAE;AAAA,IAEjD,KAAK,YAAY;AACb,aAAO,oBAAoB,MAAM,QAAQA,GAAE;AAAA,IAE/C,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,SAASA,GAAE;AAAA,IAEjD,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,SAASA,GAAE;AAAA,IAEjD,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,aAAa,SAASA,GAAE;AAAA,IAE9D;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,OAAOA,IAAG,EAAE,GAAGA,IAAG,EAAE,GAAGA,IAAG,EAAE,GAAGA,IAAG,EAAE,CAAC;AAAA,EACxD;AACJ;AAEO,SAAS,mBAAmB,OACnC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,OAAO,MAAM,QAAQ,SAAS,MAAM,QAAQ,SAAS,GAAG;AAAA,IAEnE,KAAK,YAAY;AACb,aAAO,MAAM,OAAO,OAAO,MAAM;AAAA,IAErC,KAAK,YAAY;AACb,aAAO,MAAM,QAAQ,SAAS,MAAM;AAAA,IAExC,KAAK,YAAY;AACb,aAAO,OAAO,MAAM,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAAA,IAEjE,KAAK,YAAY;AACb,aAAO,OAAO,MAAM,aAAa,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ,GAAG;AAAA,IAE3F;AACI,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,EAC9B;AACJ;AAEO,SAAS,oBAAoB,OACpC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,IAAM,SAAS,MAAM,MAAM,QAAQ,SAAS,MAAM,QAAQ,OAAO,CAAC,IAClE,IAAM,KAAK,KAAK,MAAM,QAAQ;AAAA,IAEzC,KAAK,YAAY;AACb,aAAO,IAAM,KAAK,KAAK,MAAM,OAAO;AAAA,IAExC,KAAK,YAAY,iBACjB;AACI,YAAM,SAAS,MAAM,QAAQ;AAC7B,YAAM,QAAQ,MAAM,QAAQ;AAC5B,UAAI,YAAY,IAAM,KAAK,KAAK,MAAM,QAAQ;AAC9C,cAAQ,OAAO,QAAQ,CAAC;AACxB,UAAI,OAAO,OAAO,QAAQ,CAAC;AAE3B,eAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,cAAM,OAAO,OAAO,CAAC;AACrB,qBAAa,SAAS,MAAM,MAAM,IAAI,CAAC;AACvC,eAAO;AAAA,MACX;AAEA,aAAO;AAAA,IACX;AAAA,IAEA,KAAK,YAAY;AACb,aAAO,IAAM,SAAS,MAAM,MAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA,IAE3E,KAAK,YAAY;AACb,aAAO,IAAM,SAAS,MAAM,MAAM,aAAa,QAAQ,QAAQ,MAAM,aAAa,QAAQ,MAAM,CAAC;AAAA,IAErG;AACI,aAAO;AAAA,EACf;AACJ;AAEO,SAAS,mBAAmB,OACnC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,SAAS,MAAM,OAAO;AAAA,IAE5D,KAAK,YAAY;AACb,aAAO,oBAAoB,MAAM,QAAQ,MAAM,OAAO;AAAA,IAE1D,KAAK,YAAY;AACb,aAAO,qBAAqB,MAAM,SAAS,MAAM,OAAO;AAAA,IAE5D;AACI,aAAO,IAAI,WAAW;AAAA,EAC9B;AACJ;AAEO,SAAS,qBAAqB,OAAO,aAC5C;AACI,QAAM,SAAS,IAAI,cAAc;AAEjC,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb;AACI,cAAM,SAAS,MAAM,QAAQ;AAC7B,eAAO,YAAY;AACnB,cAAM,KAAK,MAAM,MAAM,QAAQ,SAAS,WAAW;AACnD,cAAM,KAAK,MAAM,MAAM,QAAQ,SAAS,WAAW;AACnD,eAAO,YAAY,KAAK,KAAK,KAAK,IAAI,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC,IAAI;AAAA,MACvF;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,SAAS,MAAM,OAAO;AAC5B,eAAO,YAAY;AACnB,eAAO,YAAY,SAAS,MAAM,MAAM,OAAO,QAAQ,WAAW,CAAC,IAAI;AAAA,MAC3E;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,OAAO,MAAM;AACnB,YAAI,YAAY,OAAO;AACvB,YAAI,eAAe;AACnB,cAAM,QAAQ,KAAK;AAEnB,iBAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,gBAAM,IAAI,KAAK,SAAS,CAAC;AACzB,gBAAM,cAAc,MAAM,KAAK,QAAQ,CAAC,GAAG,MAAM,GAAG,KAAK,QAAQ,CAAC;AAClE,sBAAY,KAAK,IAAI,WAAW,WAAW;AAE3C,gBAAM,cAAc,gBAAgB,MAAM,GAAG,WAAW,CAAC;AACzD,yBAAe,KAAK,IAAI,cAAc,WAAW;AAAA,QACrD;AAEA,eAAO,YAAY,YAAY,KAAK;AACpC,eAAO,YAAY,KAAK,KAAK,YAAY,IAAI,KAAK;AAAA,MACtD;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,eAAO,YAAY;AACnB,cAAM,KAAK,MAAM,MAAM,QAAQ,QAAQ,WAAW;AAClD,cAAM,KAAK,MAAM,MAAM,QAAQ,QAAQ,WAAW;AAClD,eAAO,YAAY,KAAK,KAAK,KAAK,IAAI,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC;AAAA,MACnF;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,eAAO,YAAY;AACnB,cAAM,KAAK,MAAM,MAAM,aAAa,QAAQ,QAAQ,WAAW;AAC/D,cAAM,KAAK,MAAM,MAAM,aAAa,QAAQ,QAAQ,WAAW;AAC/D,eAAO,YAAY,KAAK,KAAK,KAAK,IAAI,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC;AAAA,MACnF;AAEA;AAAA,IAEJ;AACI;AAAA,EACR;AAEA,SAAO;AACX;AAEA,IAAMC,YAAW,IAAI,OAAO,GAAG,CAAC;AAChC,IAAMC,aAAY,IAAI,OAAO,GAAG,CAAC;AAE1B,SAAS,eAAe,OAAO,OAAO,WAC7C;AACI,QAAM,aAAa;AACnB,aAAW,SAAS,oBAAoB,WAAW,MAAM,MAAM;AAC/D,aAAW,cAAc,kBAAkB,UAAU,GAAG,MAAM,WAAW;AAEzE,MAAI,SAAS,IAAI,aAAa;AAC9B,SAAO,MAAM;AACb,SAAO,WAAW;AAClB,SAAO,SAAS,IAAI,OAAO,GAAG,CAAC;AAC/B,SAAO,QAAQ,IAAI,OAAO,GAAG,CAAC;AAE9B,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,eAAS,iBAAiB,YAAY,MAAM,OAAO;AAEnD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,gBAAgB,YAAY,MAAM,MAAM;AAEjD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,YAAY,MAAM,OAAO;AAEnD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,YAAY,MAAM,SAAS,KAAK;AAE1D;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,YAAY,MAAM,aAAa,SAAS,IAAI;AAEtE;AAAA,IAEJ;AACI,aAAO;AAAA,EACf;AAEA,SAAO,QAAQ,iBAAiB,WAAW,OAAO,KAAK;AACvD,SAAO,SAAS,eAAe,UAAU,GAAG,OAAO,MAAM;AAEzD,SAAO;AACX;AAEO,SAAS,iBAAiB,OAAO,OAAO,WAC/C;AACI,QAAM,aAAa;AAEnB,WAAS,IAAI,GAAG,IAAI,WAAW,OAAO,EAAE,GACxC;AACI,eAAW,OAAO,CAAC,IAAI,oBAAoB,WAAW,MAAM,OAAO,CAAC,CAAC;AAAA,EACzE;AAEA,aAAW,cAAc,kBAAkB,UAAU,GAAG,MAAM,WAAW;AAEzE,MAAI,SAAS,IAAI,aAAa;AAC9B,SAAO,MAAM;AACb,SAAO,WAAW;AAClB,SAAO,SAAS,IAAI,OAAO,GAAG,CAAC;AAC/B,SAAO,QAAQ,IAAI,OAAO,GAAG,CAAC;AAE9B,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,eAAS,mBAAmB,YAAY,MAAM,OAAO;AAErD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,kBAAkB,YAAY,MAAM,MAAM;AAEnD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,mBAAmB,YAAY,MAAM,OAAO;AAErD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,mBAAmB,YAAY,MAAM,OAAO;AAErD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,mBAAmB,YAAY,MAAM,aAAa,OAAO;AAElE;AAAA,IAEJ;AACI,aAAO;AAAA,EACf;AAEA,SAAO,QAAQ,iBAAiB,WAAW,OAAO,KAAK;AACvD,SAAO,SAAS,eAAe,UAAU,GAAG,OAAO,MAAM;AAEzD,SAAO;AACX;AAEO,SAAS,mBAAmB,OAAO,IAAI,MAAM,WAAW,mBAC/D;AACI,UAAQ,OAAO,MAAM,YAAY,aAAa;AAE9C,qBAAmB,OAAO,WAAW,IAAI;AAGzC,QAAM,WAAW,yBAAyB,IAAI,MAAM,MAAM,SAAS,MAAM,OAAO,cAAc,MAAM,IAAI,iBAAiB;AACzH,UAAQ,OAAO,cAAc,MAAM,QAAQ,IAAI,WAAW,gBAAgB;AAC9E;AAEO,SAAS,oBAAoB,OAAO,IAC3C;AACI,MAAI,MAAM,YAAY,eACtB;AACI,8BAA0B,IAAI,MAAM,QAAQ;AAC5C,UAAM,WAAW;AAAA,EACrB;AACJ;AAEO,SAAS,yBAAyB,OACzC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,YAAY,CAAE,MAAM,QAAQ,QAAQ,MAAM,GAAG,MAAM,QAAQ,QAAQ,MAAM,CAAE,GAAG,GAAG,MAAM,QAAQ,MAAM;AAAA,IAEhH,KAAK,YAAY;AACb,aAAO,YAAY,CAAE,MAAM,OAAO,OAAO,MAAM,CAAE,GAAG,GAAG,MAAM,OAAO,MAAM;AAAA,IAE9E,KAAK,YAAY;AACb,aAAO,YAAY,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAAO,MAAM,QAAQ,MAAM;AAAA,IAExF,KAAK,YAAY;AACb,aAAO,YAAY,CAAE,MAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAO,GAAG,GAAG,CAAG;AAAA,IAE7E,KAAK,YAAY;AACb,aAAO,YAAY,CAAE,MAAM,aAAa,QAAQ,OAAO,MAAM,GAAG,MAAM,aAAa,QAAQ,OAAO,MAAM,CAAE,GAAG,GAAG,CAAG;AAAA,IAEvH;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,gBAAgB;AAAA,EACnC;AACJ;AAYO,SAAS,gBAAgB,SAChC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,aAAa,OAAO,MAAM,MAAM;AAC3C;AAoBO,SAAS,oBAAoB,SAAS,UAC7C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,WAAW;AACrB;AAWO,SAAS,oBAAoB,SACpC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAYO,SAAS,iBAAiB,SACjC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAaO,SAAS,kBAAkB,SAAS,OAC3C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,QAAM,YAAY,oBAAoB,OAAO,KAAK;AAClD,QAAM,aAAa,oBAAoB,WAAW,KAAK;AAEvD,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,iBAAiB,YAAY,MAAM,OAAO;AAAA,IAErD,KAAK,YAAY;AACb,aAAO,gBAAgB,YAAY,MAAM,MAAM;AAAA,IAEnD,KAAK,YAAY;AACb,aAAO,iBAAiB,YAAY,MAAM,OAAO;AAAA,IAErD;AACI,aAAO;AAAA,EACf;AACJ;AAiBO,SAAS,gBAAgB,SAAS,QAAQ,aACjD;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,QAAM,YAAY,oBAAoB,OAAO,KAAK;AAGlD,QAAM,QAAQ,IAAI,eAAe;AACjC,QAAM,cAAc;AACpB,QAAM,SAAS,oBAAoB,WAAW,MAAM;AACpD,QAAM,cAAc,kBAAkB,UAAU,GAAG,WAAW;AAE9D,MAAI,SAAS,IAAI,aAAaC,YAAWC,SAAQ;AAEjD,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,eAAS,iBAAiB,OAAO,MAAM,OAAO;AAE9C;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,gBAAgB,OAAO,MAAM,MAAM;AAE5C;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,OAAO,MAAM,SAAS,KAAK;AAErD;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,OAAO,MAAM,OAAO;AAE9C;AAAA,IAEJ,KAAK,YAAY;AACb,eAAS,iBAAiB,OAAO,MAAM,aAAa,SAAS,IAAI;AAEjE;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO;AAAA,EACf;AAEA,MAAI,OAAO,KACX;AAEI,WAAO,SAAS,eAAe,UAAU,GAAG,OAAO,MAAM;AACzD,WAAO,QAAQ,iBAAiB,WAAW,OAAO,KAAK;AAAA,EAC3D;AAEA,SAAO;AACX;AAcO,SAAS,mBAAmB,SAAS,SAC5C;AACI,UAAQ,OAAO,UAAU,OAAO,KAAK,WAAW,CAAG;AAEnD,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,SAAS,MACb;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,MAAI,WAAW,MAAM,SACrB;AAEI;AAAA,EACJ;AAEA,QAAM,UAAU;AACpB;AAYO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAeO,SAAS,oBAAoB,SAAS,UAC7C;AACI,UAAQ,OAAO,UAAU,QAAQ,KAAK,YAAY,CAAG;AAErD,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,WAAW;AACrB;AAWO,SAAS,oBAAoB,SACpC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAWO,SAAS,uBAAuB,SAAS,aAChD;AACI,UAAQ,OAAO,UAAU,WAAW,KAAK,eAAe,CAAG;AAE3D,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,cAAc;AACxB;AAWO,SAAS,uBAAuB,SACvC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAYO,SAAS,kBAAkB,SAClC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAGA,SAAS,aAAa,OAAO,OAAO,YAAY,cAChD;AACI,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAE1C,QAAM,UAAU,MAAM;AAGtB,MAAI,aAAa,KAAK;AAEtB,SAAO,eAAe,eACtB;AACI,UAAM,YAAY,cAAc;AAChC,UAAM,YAAY,aAAa;AAG/B,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,iBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,QAAI,QAAQ,aAAa,WAAW,QAAQ,aAAa,SACzD;AACI,uBAAiB,OAAO,SAAS,UAAU;AAAA,IAC/C;AAAA,EACJ;AAEA,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,MAAI,MAAM,aAAa,eACvB;AACI,UAAM,YAAY,cAAc,MAAM,QAAQ;AAC9C,uBAAmB,OAAO,WAAW,SAAS;AAE9C,QAAI,cACJ;AACI,gCAA0B,MAAM,YAAY,MAAM,QAAQ;AAE1D,YAAM,oBAAoB;AAC1B,YAAM,WAAW;AAAA,QAAyB,MAAM;AAAA,QAAY;AAAA,QAAW,MAAM;AAAA,QAAS,MAAM,OAAO;AAAA,QAC/F;AAAA,QAAS;AAAA,MAAiB;AAAA,IAClC,OAEA;AACI,6BAAuB,MAAM,YAAY,MAAM,UAAU,MAAM,OAAO;AAAA,IAC1E;AAAA,EACJ,OAEA;AACI,UAAM,YAAY,KAAK;AACvB,uBAAmB,OAAO,WAAW,SAAS;AAAA,EAClD;AAEA,uBAAqB,KAAK;AAC9B;AAcO,SAAS,kBAAkB,SAAS,QAC3C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,MAAI,OAAO,aAAa,MAAM,OAAO,YAAY,OAAO,iBAAiB,MAAM,OAAO,gBAClF,OAAO,eAAe,MAAM,OAAO,YACvC;AACI;AAAA,EACJ;AAGA,QAAM,eAAe,OAAO,iBAAiB,MAAM,OAAO;AAE1D,QAAM,SAAS;AAGf,QAAM,aAAa;AACnB,eAAa,OAAO,OAAO,YAAY,YAAY;AACvD;AAYO,SAAS,2BAA2B,SAAS,MACpD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,qBAAqB;AAC/B;AAWO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAYO,SAAS,4BAA4B,SAAS,MACrD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,sBAAsB;AAChC;AAWO,SAAS,gCAAgC,SAChD;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAYO,SAAS,6BAA6B,SAAS,MACtD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,uBAAuB;AACjC;AAWO,SAAS,iCAAiC,SACjD;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAaO,SAAS,wBAAwB,SAAS,MACjD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,kBAAkB;AAC5B;AAWO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAWO,SAAS,gBAAgB,SAChC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAUO,SAAS,kBAAkB,SAClC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAQ,OAAO,MAAM,SAAS,YAAY,cAAc;AAExD,SAAO,MAAM;AACjB;AAUO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAQ,OAAO,MAAM,SAAS,YAAY,eAAe;AAEzD,SAAO,MAAM;AACjB;AAUO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAQ,OAAO,MAAM,SAAS,YAAY,oBAAoB;AAE9D,SAAO,MAAM;AACjB;AAUO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAQ,OAAO,MAAM,SAAS,YAAY,eAAe;AAEzD,SAAO,MAAM;AACjB;AASO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAQ,OAAO,MAAM,SAAS,YAAY,eAAe;AAEzD,SAAO,MAAM;AACjB;AAYO,SAAS,kBAAkB,SAAS,QAC3C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,SAAS;AACf,QAAM,OAAO,YAAY;AAGzB,QAAM,aAAa;AACnB,QAAM,eAAe;AACrB,eAAa,OAAO,OAAO,YAAY,YAAY;AACvD;AAaO,SAAS,mBAAmB,SAAS,SAC5C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,UAAU;AAChB,QAAM,OAAO,YAAY;AAGzB,QAAM,aAAa;AACnB,QAAM,eAAe;AACrB,eAAa,OAAO,OAAO,YAAY,YAAY;AACvD;AAYO,SAAS,mBAAmB,SAAS,SAC5C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,UAAU;AAChB,QAAM,OAAO,YAAY;AAGzB,QAAM,aAAa;AACnB,QAAM,eAAe;AACrB,eAAa,OAAO,OAAO,YAAY,YAAY;AACvD;AAaO,SAAS,mBAAmB,SAAS,SAC5C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,UAAU;AAChB,QAAM,OAAO,YAAY;AAGzB,QAAM,aAAa;AACnB,QAAM,eAAe;AACrB,eAAa,OAAO,OAAO,YAAY,YAAY;AACvD;AAYO,SAAS,uBAAuB,SACvC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,MAAI,MAAM,SAAS,YAAY,sBAC/B;AACI,UAAM,UAAU,MAAM,aAAa;AAEnC,QAAI,YAAY,eAChB;AAEI,YAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,aAAO,IAAI,UAAU,UAAU,GAAG,QAAQ,QAAQ,MAAM,QAAQ;AAAA,IACpE;AAAA,EACJ;AAEA,SAAO,IAAI,UAAU;AACzB;AAaO,SAAS,oBAAoB,SAAS,UAC7C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,aAAa,gBAAgB,OAAO,OAAO;AAEjD,QAAM,QAAQ,WAAW;AAEzB,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAM,UAAU,WAAW,aAAa,CAAC;AAGzC,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,WAAW;AAAA,EACrB;AACJ;AAYO,SAAS,uBAAuB,SAAS,aAChD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,aAAa,gBAAgB,OAAO,OAAO;AAEjD,QAAM,QAAQ,WAAW;AAEzB,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAM,UAAU,WAAW,aAAa,CAAC;AAGzC,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,cAAc;AAAA,EACxB;AACJ;AAYO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,MAAI,MAAM,UACV;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAG1C,SAAO,KAAK;AAChB;AAcO,SAAS,uBAAuB,SAAS,aAAa,UAC7D;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,MAAI,MAAM,UACV;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,MAAI,aAAa,KAAK;AACtB,MAAI,QAAQ;AAEZ,SAAO,eAAe,iBAAiB,QAAQ,UAC/C;AACI,UAAM,YAAY,cAAc;AAChC,UAAM,YAAY,aAAa;AAG/B,UAAM,UAAU,MAAM,aAAa,SAAS;AAG5C,SAAK,QAAQ,aAAa,QAAQ,SAAS,KAAK,QAAQ,aAAa,QAAQ,SAAS,OACjF,QAAQ,QAAQ,eAAe,4BAA4B,GAChE;AACI,YAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAChD,YAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAEhD,kBAAY,KAAK,EAAE,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,QAAQ,QAAQ,OAAO,QAAQ;AAC1F,kBAAY,KAAK,EAAE,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,QAAQ,QAAQ,OAAO,QAAQ;AAE1F,YAAM,aAAa,gBAAgB,OAAO,OAAO;AACjD,kBAAY,KAAK,EAAE,WAAW,WAAW;AACzC,eAAS;AAAA,IACb;AAEA,iBAAa,QAAQ,MAAM,SAAS,EAAE;AAAA,EAC1C;AAEA,UAAQ,OAAO,SAAS,QAAQ;AAEhC,SAAO;AACX;AAWO,SAAS,gBAAgB,SAChC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AAEvC,MAAI,UAAU,MACd;AACI,WAAO,IAAI,OAAO;AAAA,EACtB;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,SAAO,MAAM;AACjB;AAaO,SAAS,wBAAwB,SAAS,QACjD;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AAEvC,MAAI,UAAU,MACd;AACI,WAAO,IAAI,OAAO,GAAG,CAAC;AAAA,EAC1B;AAEA,QAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,yBAAyB,KAAK;AAC7C,QAAM,SAAS,YAAY,CAAE,MAAO,GAAG,GAAG,CAAG;AAC7C,QAAM,aAAa;AACnB,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,WAAW;AAEjB,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,SAAO,OAAO;AAClB;;;ACh8DO,IAAM,UAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,KAAK;AACV,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,OAAO,YAAY;AACxB,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,cAAc;AAEnB,SAAK,OAAO,IAAI,OAAO;AACvB,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,WAAW;AAEhB,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,WAAW;AAChB,SAAK,cAAc;AAEnB,SAAK,UAAU,IAAI,UAAU;AAC7B,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,UAAU,IAAI,UAAU;AAC7B,SAAK,UAAU,IAAI,UAAU;AAC7B,SAAK,eAAe,IAAI,eAAe;AAEvC,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB;AAC3B,SAAK,kBAAkB;AACvB,SAAK,uBAAuB;AAC5B,SAAK,eAAe;AACpB,SAAK,SAAS;AAEd,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,YAAY;AAAA,EACrB;AACJ;AAEO,IAAM,eAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,KAAK;AACV,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,eAAe,CAAC;AACrB,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EACrB;AACJ;;;AC/DA,IAAM,YAAY;AAEX,SAAS,eAAe,aAC/B;AACI,QAAM,SAAS,IAAI,SAAS;AAC5B,QAAM,MAAM,KAAK,OAAO,cAAc,YAAY,IAAI,MAAM,YAAY,EAAE;AAE1E,SAAO,gBAAgB;AACvB,SAAO,aAAa;AACpB,SAAO,OAAO,IAAI,eAAe,OAAO,aAAa;AACrD,SAAO,KAAK,KAAK,EAAE;AAEnB,SAAO;AACX;AAEO,SAAS,gBAAgB,QAChC;AACI,SAAO,gBAAgB;AACvB,SAAO,aAAa;AACpB,SAAO,OAAO;AAClB;AAEO,SAAS,sBAAsB,QAAQ,UAC9C;AACI,QAAM,aAAa,KAAK,OAAO,WAAW,YAAY,IAAI,MAAM,YAAY,EAAE;AAE9E,MAAI,OAAO,gBAAgB,YAC3B;AACI,oBAAgB,MAAM;AACtB,UAAM,iBAAiB,YAAY,YAAY;AAC/C,aAAS,eAAe,cAAc;AAAA,EAC1C;AAEA,SAAO,aAAa;AACpB,SAAO,KAAK,KAAK,EAAE;AAEnB,SAAO;AACX;AAwBO,SAAS,eAAe,MAAM,MACrC;AACI,UAAQ,OAAO,KAAK,cAAc,KAAK,UAAU;AACjD,QAAM,aAAa,KAAK;AAExB,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,SAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC;AAAA,EAC/B;AACJ;;;ACnEO,IAAM,WAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAAA,EACtB;AACJ;AAMO,SAAS,SAAS,QAAQ,UACjC;AACI,QAAM,aAAa,KAAK,MAAM,WAAW,EAAE;AAC3C,UAAQ,OAAO,aAAa,OAAO,UAAU;AAC7C,SAAO,KAAK,UAAU,KAAM,OAAO,CAAC,KAAK,OAAO,WAAW,EAAE;AACjE;AAcO,SAAS,WAAW,QAAQ,UACnC;AACI,QAAM,aAAa,KAAK,MAAM,WAAW,EAAE;AAE3C,MAAI,cAAc,OAAO,YACzB;AACI;AAAA,EACJ;AAEA,SAAO,KAAK,UAAU,KAAK,EAAE,OAAO,CAAC,KAAK,OAAO,WAAW,EAAE;AAClE;AAEO,SAAS,SAAS,QAAQ,UACjC;AACI,QAAM,aAAa,KAAK,MAAM,WAAW,EAAE;AAE3C,MAAI,cAAc,OAAO,YACzB;AACI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,KAAK,UAAU,IAAK,OAAO,CAAC,KAAK,OAAO,WAAW,EAAE,OAAQ,OAAO,CAAC;AACxF;;;ACrDO,IAAM,mBAAmB,qBAAqB;AAE9C,IAAM,eAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU,IAAI,SAAS;AAC5B,SAAK,WAAW,IAAI,eAAe;AACnC,SAAK,SAAS,IAAI,aAAa;AAC/B,SAAK,sBAAsB;AAAA,EAC/B;AACJ;AAEO,IAAM,oBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS,CAAC;AAEf,aAAS,IAAI,GAAG,IAAI,oBAAoB,KACxC;AAAE,WAAK,OAAO,KAAK,IAAI,aAAa,CAAC;AAAA,IAAG;AAAA,EAC5C;AACJ;AAEO,SAAS,cAAc,OAAO,cACrC;AACI,UAAQ,OAAQ,sBAAsB,GAAG,gDAAiD;AAC1F,UAAQ,OAAQ,oBAAoB,qBAAqB,GAAG,qBAAqB;AAEjF,UAAQ,IAAI,kBAAkB;AAE9B,iBAAe,KAAK,IAAI,cAAc,CAAC;AAEvC,WAAS,IAAI,GAAG,IAAI,kBAAkB,KACtC;AACI,UAAM,QAAQ,MAAM,OAAO,CAAC;AAC5B,UAAM,UAAU,eAAe,YAAY;AAC3C,UAAM,UAAU,sBAAsB,MAAM,SAAS,YAAY;AAAA,EACrE;AAEA,SAAO;AACX;AAEO,SAAS,eAAe,OAC/B;AACI,WAAS,IAAI,GAAG,IAAI,oBAAoB,KACxC;AACI,UAAM,QAAQ,MAAM,OAAO,CAAC;AAG5B,oBAAgB,MAAM,OAAO;AAAG,UAAM,UAAU;AAChD,UAAM,WAAW;AACjB,UAAM,SAAS;AAAA,EACnB;AACJ;AAEO,SAAS,oBAAoB,OAAO,YAAY,SACvD;AACI,MAAI,WAAW,SAAS,cAAc,GACtC;AACI,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACvE;AAEA,MAAI,EAAE,WAAW,WAAW,kBAAkB,qBAC9C;AACI,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC7E;AAEA,MAAI,EAAE,QAAQ,QAAQ,eAAe,yBACrC;AACI,UAAM,IAAI,MAAM,uDAAuD;AAAA,EAC3E;AAEA,QAAM,QAAQ,MAAM;AACpB,QAAM,aAAa;AAEnB,QAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,QAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,eAAa,MAAM,WAAW,OAAO;AACrC,eAAa,MAAM,WAAW,OAAO;AAErC,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,QAAM,UAAU,MAAM,YAAY,UAAU;AAC5C,QAAM,UAAU,MAAM,YAAY,UAAU;AAE5C,MAAI,WAAW,SACf;AACI,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACzE;AAEA,QAAM,QAAQ,MAAM,OAAO,UAAU;AACrC,UAAQ,aAAa;AACrB,UAAQ,aAAa,MAAM,SAAS;AAEpC,QAAM,aAAa,aAAa,MAAM,QAAQ;AAC9C,aAAW,IAAI,UAAU;AAEzB,MAAI,SACJ;AACI,eAAW,gBAAgB;AAC3B,eAAW,WAAW;AACtB,eAAW,QAAQ;AAAA,EACvB,OAEA;AACI,QAAI,MAAM,aAAa,UAAU,aACjC;AACI,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC5E;AACA,UAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAE3D,UAAM,aAAa,MAAM;AAEzB,QAAI,EAAE,KAAK,cAAc,aAAa,SAAS,KAAK,QACpD;AACI,YAAM,IAAI,MAAM,oEAAoE;AAAA,IACxF;AACA,eAAW,gBAAgB;AAE3B,UAAM,WAAW,SAAS,KAAK,KAAK,UAAU;AAC9C,eAAW,WAAW,SAAS;AAC/B,eAAW,QAAQ,SAAS;AAAA,EAChC;AAEA,MAAI,SACJ;AACI,eAAW,gBAAgB;AAC3B,eAAW,WAAW;AACtB,eAAW,QAAQ;AAAA,EACvB,OAEA;AACI,QAAI,MAAM,aAAa,UAAU,aACjC;AACI,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC5E;AACA,UAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAE3D,UAAM,aAAa,MAAM;AAEzB,QAAI,EAAE,KAAK,cAAc,aAAa,SAAS,KAAK,QACpD;AACI,YAAM,IAAI,MAAM,oEAAoE;AAAA,IACxF;AACA,eAAW,gBAAgB;AAE3B,UAAM,WAAW,SAAS,KAAK,KAAK,UAAU;AAC9C,eAAW,WAAW,SAAS;AAC/B,eAAW,QAAQ,SAAS;AAAA,EAChC;AACJ;AAEO,SAAS,yBAAyB,OAAO,SAAS,SAAS,YAAY,YAC9E;AACI,QAAM,QAAQ,MAAM;AAEpB,MAAI,eAAe,kBACnB;AACI,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AACA,QAAM,QAAQ,MAAM,OAAO,UAAU;AAErC,MAAK,cAAc,kBACnB;AAEI,eAAY,MAAM,SAAS,OAAQ;AACnC,eAAY,MAAM,SAAS,OAAQ;AAAA,EACvC;AAEA,QAAM,aAAa,gBAAgB,MAAM,UAAU,UAAU;AAE7D,MAAI,eAAe,eACnB;AAEI,UAAM,kBAAkB,MAAM,SAAS,KAAK,UAAU;AAGtD,UAAM,UAAU,gBAAgB;AAChC,UAAM,eAAe,MAAM,aAAa,OAAO;AAE/C,QAAI,aAAa,aAAa,UAAU,aACxC;AACI,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACnF;AAEA,QAAI,aAAa,eAAe,YAChC;AACI,YAAM,IAAI,MAAM,sDAAsD;AAAA,IAC1E;AAEA,QAAI,aAAa,eAAe,YAChC;AACI,YAAM,IAAI,MAAM,sDAAsD;AAAA,IAC1E;AACA,iBAAa,aAAa;AAAA,EAC9B;AACJ;AAEA,SAAS,mBAAmB,OAAO,SAAS,SAAS,SAAS,SAC9D;AACI,UAAQ,OAAQ,WAAW,SAAS,WAAW,KAAM;AAErD,SAAO;AACX;AAEO,SAAS,qBAAqB,OAAO,OAC5C;AACI,QAAM,QAAQ,MAAM;AAEpB,QAAM,UAAU,MAAM,MAAM,CAAC,EAAE;AAC/B,QAAM,UAAU,MAAM,MAAM,CAAC,EAAE;AAK/B,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,QAAM,UAAU,MAAM,aAAa,UAAU;AAC7C,QAAM,UAAU,MAAM,aAAa,UAAU;AAE7C,MAAI,WAAW,SACf;AACI,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACzE;AAEA,QAAM,aAAa,mBAAoB,OAAO,SAAS,SAAS,SAAS,OAAQ;AAEjF,QAAM,WAAW,WAAW,MAAM,OAAO,UAAU,EAAE,MAAM;AAC3D,QAAM,aAAa;AACnB,QAAM,aAAa,MAAM,OAAO,UAAU,EAAE,OAAO,QAAQ;AAE3D,SAAO;AACX;AAEO,SAAS,kBAAkB,OAAO,UAAU,OACnD;AACI,QAAM,WAAW,qBAAqB,OAAO,KAAK;AAClD,SAAO,OAAO,UAAU,QAAQ;AACpC;AAEO,SAAS,uBAAuB,OAAO,SAAS,SAAS,YAAY,YAC5E;AACI,QAAM,QAAQ,MAAM;AAEpB,UAAQ,OAAO,KAAK,cAAc,aAAa,kBAAkB;AACjE,QAAM,QAAQ,MAAM,OAAO,UAAU;AAErC,MAAI,cAAc,kBAClB;AACI,eAAW,MAAM,SAAS,OAAO;AACjC,eAAW,MAAM,SAAS,OAAO;AAAA,EACrC;AAGA,QAAM,aAAa,cAAc,MAAM,QAAQ,UAAU;AAEzD,MAAI,eAAe,eACnB;AAEI,UAAM,gBAAgB,MAAM,OAAO,KAAK,UAAU;AAClD,UAAM,UAAU,cAAc;AAG9B,QAAI,WAAW,MAAM,WAAW,OAAO,EAAE,SACzC;AACI,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACvD;AAEA,UAAM,aAAa,MAAM,WAAW,OAAO;AAE3C,QAAI,WAAW,aAAa,UAAU,aACtC;AACI,YAAM,IAAI,MAAM,6DAA6D;AAAA,IACjF;AAEA,QAAI,WAAW,eAAe,YAC9B;AACI,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACxE;AAEA,QAAI,WAAW,eAAe,YAC9B;AACI,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACxE;AAEA,eAAW,aAAa;AAAA,EAC5B;AACJ;;;ACjSO,IAAM,sBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,WAAW,IAAI,WAAW;AAC/B,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,SAAS,CAAC;AAAA,EACnB;AACJ;AAEO,IAAM,2BAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AAAA,EAC5B;AACJ;AAEO,SAAS,0BAA0B,SAC1C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,cAAc,MAAM;AAC1B,QAAM,eAAe,MAAM,SAAS;AACpC,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,cAAc,QAAQ;AAI5B,QAAM,kBAAkB,QAAQ;AAChC,QAAM,iBAAiB,QAAQ;AAE/B,QAAM,iBAAiB,MAAM,qBAAqB,IAAM;AAExD,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,SAAS,CAAC;AAC7B,UAAM,WAAW,WAAW;AAC5B,UAAM,aAAa,SAAS;AAE5B,UAAM,SAAS,WAAW;AAC1B,UAAM,SAAS,WAAW;AAY1B,UAAM,aAAa,YAAY,CAAC;AAChC,eAAW,SAAS;AACpB,eAAW,SAAS;AACpB,eAAW,UAAU,SAAS;AAC9B,eAAW,UAAU,SAAS;AAC9B,eAAW,WAAW,WAAW;AACjC,eAAW,cAAc,WAAW;AACpC,eAAW,aAAa;AAGxB,QAAI,MAAM;AACV,QAAI,MAAM;AACV,QAAI,KAAK;AACT,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AAEtB,QAAI,WAAW,eACf;AACI,YAAM,SAAS,YAAY,MAAM;AACjC,YAAM,OAAO,eAAe;AAC5B,YAAM,OAAO,eAAe;AAC5B,WAAK,OAAO;AAAA,IAChB;AAGA,QAAI,MAAM;AACV,QAAI,MAAM;AACV,QAAI,KAAK;AACT,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AAEtB,QAAI,WAAW,eACf;AACI,YAAM,SAAS,YAAY,MAAM;AACjC,YAAM,OAAO,eAAe;AAC5B,YAAM,OAAO,eAAe;AAC5B,WAAK,OAAO;AAAA,IAChB;AAEA,eAAW,WAAY,WAAW,iBAAiB,WAAW,gBAAiB,iBAAiB;AAEhG,eAAW,WAAW;AACtB,eAAW,QAAQ;AACnB,eAAW,WAAW;AACtB,eAAW,QAAQ;AAEnB,UAAM,UAAU,WAAW;AAC3B,UAAM,UAAU,WAAW;AAG3B,UAAM,WAAW,WAAW;AAC5B,UAAM,WAAW,CAAC,WAAW;AAE7B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,YAAM,KAAK,WAAW,OAAO,CAAC,IAAI,IAAI,yBAAyB;AAE/D,SAAG,gBAAgB,iBAAiB,GAAG;AACvC,SAAG,iBAAiB,iBAAiB,GAAG;AACxC,SAAG,mBAAmB;AAGtB,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAGf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAGf,SAAG,WAAW;AACd,SAAG,WAAW;AAGd,SAAG,WAAW;AACd,SAAG,WAAW;AACd,YAAM,OAAO,MAAM;AACnB,YAAM,OAAO,MAAM;AAGnB,SAAG,iBAAiB,GAAG,cAAc,OAAO,UAAU,OAAO;AAG7D,YAAM,MAAM,MAAM,UAAU,MAAM;AAGlC,YAAM,MAAM,MAAM,UAAU,MAAM;AAClC,YAAM,UAAU,KAAK,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM;AACtD,SAAG,aAAa,UAAU,IAAM,IAAM,UAAU;AAGhD,YAAM,MAAM,MAAM,WAAW,MAAM;AAGnC,YAAM,MAAM,MAAM,WAAW,MAAM;AACnC,YAAM,WAAW,KAAK,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM;AACvD,SAAG,cAAc,WAAW,IAAM,IAAM,WAAW;AAGnD,YAAM,OAAO,MAAO,CAAC,KAAK;AAC1B,YAAM,OAAO,MAAO,KAAK;AAGzB,YAAM,OAAO,MAAO,CAAC,KAAK;AAC1B,YAAM,OAAO,MAAO,KAAK;AAGzB,SAAG,mBAAmB,WAAW,OAAO,QAAQ,WAAW,OAAO;AAAA,IACtE;AAAA,EACJ;AACJ;AAEO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,cAAc,MAAM;AAC1B,QAAM,eAAe,MAAM,SAAS;AACpC,QAAM,WAAW,QAAQ,MAAM,eAAe,UAAU,WAAW;AACnE,QAAM,SAAS,SAAS,OAAO;AAE/B,QAAM,aAAa,IAAI,YAAY;AAEnC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,YAAY,CAAC;AAEhC,UAAM,SAAS,WAAW;AAC1B,UAAM,SAAS,WAAW;AAE1B,UAAM,SAAS,WAAW,gBAAgB,aAAa,OAAO,MAAM;AACpE,UAAM,SAAS,WAAW,gBAAgB,aAAa,OAAO,MAAM;AAEpE,UAAM,KAAK,OAAO;AAClB,QAAI,KAAK,OAAO;AAChB,UAAM,KAAK,OAAO;AAClB,QAAI,KAAK,OAAO;AAEhB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AAEtB,UAAM,UAAU,WAAW;AAC3B,UAAM,UAAU,WAAW;AAG3B,UAAM,WAAW,WAAW;AAC5B,UAAM,WAAW,CAAC,WAAW;AAC7B,UAAM,aAAa,WAAW;AAE9B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,KAAK,WAAW,OAAO,CAAC;AAC9B,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAGf,YAAM,KAAM,GAAG,gBAAgB,UAAY,GAAG,iBAAiB;AAC/D,YAAM,KAAM,GAAG,gBAAgB,UAAY,GAAG,iBAAiB;AAG/D,YAAM,MAAM,MAAM,KAAK,MAAM;AAG7B,SAAG,KAAK,KAAK;AACb,SAAG,KAAK,KAAK;AAGb,YAAM,MAAM,MAAM,KAAK,MAAM;AAG7B,SAAG,KAAK,KAAK;AACb,SAAG,KAAK,KAAK;AAAA,IACjB;AAEA,WAAO,iBAAiB;AACxB,WAAO,kBAAkB;AACzB,WAAO,iBAAiB;AACxB,WAAO,kBAAkB;AAAA,EAC7B;AACJ;AAEO,SAAS,wBAAwB,SAAS,SACjD;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,cAAc,MAAM;AAC1B,QAAM,eAAe,MAAM,SAAS;AACpC,QAAM,WAAW,QAAQ,MAAM,eAAe,UAAU,WAAW;AACnE,QAAM,SAAS,SAAS;AAExB,QAAM,QAAQ,QAAQ;AACtB,QAAM,UAAU,QAAQ,MAAM;AAG9B,QAAM,aAAa,IAAI,YAAY;AAEnC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AAEI,UAAM,aAAa,YAAY,CAAC;AAChC,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AAEtB,UAAM,SAAS,WAAW,WAAW,gBAAgB,aAAa,OAAO,KAAK,WAAW,MAAM;AAC/F,QAAI,MAAM,OAAO,eAAe;AAChC,QAAI,MAAM,OAAO,eAAe;AAChC,QAAI,KAAK,OAAO;AAChB,UAAM,MAAM,OAAO;AAEnB,UAAM,SAAS,WAAW,WAAW,gBAAgB,aAAa,OAAO,KAAK,WAAW,MAAM;AAC/F,QAAI,MAAM,OAAO,eAAe;AAChC,QAAI,MAAM,OAAO,eAAe;AAChC,QAAI,KAAK,OAAO;AAChB,UAAM,MAAM,OAAO;AAEnB,UAAM,MAAM,OAAO,cAAc,IAAI,OAAO,cAAc;AAC1D,UAAM,MAAM,OAAO,cAAc,IAAI,OAAO,cAAc;AAE1D,UAAM,UAAU,WAAW;AAC3B,UAAM,UAAU,WAAW;AAC3B,UAAM,WAAW;AACjB,UAAM,WAAW,CAAC;AAClB,UAAM,WAAW,WAAW;AAC5B,UAAM,WAAW,WAAW;AAE5B,UAAM,aAAa,WAAW;AAE9B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,KAAK,WAAW,OAAO,CAAC;AAG9B,YAAM,KAAM,IAAI,IAAI,GAAG,WAAW,IAAI,IAAI,GAAG,YAAa,IAAI,IAAI,GAAG,WAAW,IAAI,IAAI,GAAG;AAC3F,YAAM,KAAM,IAAI,IAAI,GAAG,WAAW,IAAI,IAAI,GAAG,YAAa,IAAI,IAAI,GAAG,WAAW,IAAI,IAAI,GAAG;AAC3F,YAAM,KAAK,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,GAAG;AAE3D,UAAI,eAAe;AACnB,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AACI,uBAAe,IAAI;AAAA,MACvB,WACS,SACT;AACI,uBAAe,KAAK,IAAI,SAAS,WAAW,GAAG,CAAC,OAAO;AACvD,oBAAY,SAAS;AACrB,uBAAe,SAAS;AAAA,MAC5B;AAGA,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAGf,YAAM,MAAM,MAAM,MAAM,KAAK,CAAC,MAAM,KAAK,CAAC,OAAO,WACpC,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO;AAGhD,UAAI,UAAU,CAAC,GAAG,aAAa,aAAa,KAAK,gBAAgB,eAAe,GAAG;AAGnF,YAAM,aAAa,KAAK,IAAI,GAAG,gBAAgB,SAAS,CAAG;AAC3D,gBAAU,aAAa,GAAG;AAC1B,SAAG,gBAAgB;AACnB,SAAG,mBAAmB,KAAK,IAAI,GAAG,kBAAkB,OAAO;AAG3D,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AACrB,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,YAAM,MAAM,MAAM,KAAK,MAAM;AAC7B,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,YAAM,MAAM,MAAM,KAAK,MAAM;AAAA,IACjC;AAEA,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,KAAK,WAAW,OAAO,CAAC;AAC9B,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAGf,YAAM,MAAO,MAAM,KAAK,OAAQ,MAAM,KAAK;AAC3C,YAAM,MAAO,MAAM,KAAK,OAAQ,MAAM,KAAK;AAC3C,YAAM,KAAK,MAAM,WAAW,MAAM;AAGlC,UAAI,UAAU,GAAG,cAAe,CAAC;AAGjC,YAAM,cAAc,WAAW,GAAG;AAClC,YAAM,oBAAoB,GAAG;AAC7B,SAAG,iBAAiB,oBAAoB;AACxC,SAAG,iBAAiB,GAAG,iBAAiB,CAAC,cAAc,CAAC,cACnD,GAAG,iBAAiB,cAAc,cAAc,GAAG;AACxD,gBAAU,GAAG,iBAAiB;AAG9B,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAErB,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,YAAM,MAAM,MAAM,KAAK,MAAM;AAE7B,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,YAAM,MAAM,MAAM,KAAK,MAAM;AAAA,IACjC;AAEA,WAAO,eAAe,IAAI;AAC1B,WAAO,eAAe,IAAI;AAC1B,WAAO,kBAAkB;AACzB,WAAO,eAAe,IAAI;AAC1B,WAAO,eAAe,IAAI;AAC1B,WAAO,kBAAkB;AAAA,EAC7B;AACJ;AAEO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,cAAc,MAAM;AAC1B,QAAM,eAAe,MAAM,SAAS;AACpC,QAAM,WAAW,QAAQ,MAAM,eAAe,UAAU,WAAW;AACnE,QAAM,SAAS,SAAS;AAExB,QAAM,YAAY,QAAQ,MAAM;AAGhC,QAAM,aAAa,IAAI,YAAY;AAEnC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,YAAY,CAAC;AAEhC,UAAM,cAAc,WAAW;AAE/B,QAAI,gBAAgB,GACpB;AACI;AAAA,IACJ;AAEA,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,WAAW;AAEtB,UAAM,SAAS,WAAW,WAAW,gBAAgB,aAAa,OAAO,KAAK,WAAW,MAAM;AAC/F,UAAM,KAAK,OAAO;AAClB,QAAI,KAAK,OAAO;AAEhB,UAAM,SAAS,WAAW,WAAW,gBAAgB,aAAa,OAAO,KAAK,WAAW,MAAM;AAC/F,UAAM,KAAK,OAAO;AAClB,QAAI,KAAK,OAAO;AAEhB,UAAM,UAAU,WAAW;AAC3B,UAAM,UAAU,WAAW;AAC3B,UAAM,aAAa,WAAW;AAE9B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,KAAK,WAAW,OAAO,CAAC;AAE9B,UAAI,GAAG,mBAAmB,CAAC,aAAa,GAAG,qBAAqB,GAChE;AACI;AAAA,MACJ;AAGA,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AAIf,YAAM,OAAO,GAAG,IAAI,CAAC,KAAK;AAC1B,YAAM,OAAO,GAAG,IAAI,KAAK;AAGzB,YAAM,OAAO,GAAG,IAAI,CAAC,KAAK;AAC1B,YAAM,OAAO,GAAG,IAAI,KAAK;AAGzB,YAAM,OAAO,OAAO;AACpB,YAAM,OAAO,OAAO;AACpB,YAAM,KAAK,OAAO,UAAU,OAAO;AAGnC,UAAI,UAAU,CAAC,GAAG,cAAc,KAAK,cAAc,GAAG;AAGtD,YAAM,aAAa,KAAK,IAAI,GAAG,gBAAgB,SAAS,CAAG;AAC3D,gBAAU,aAAa,GAAG;AAC1B,SAAG,gBAAgB;AACnB,SAAG,mBAAmB,KAAK,IAAI,GAAG,kBAAkB,OAAO;AAI3D,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAGrB,SAAG,KAAK,KAAK;AACb,SAAG,KAAK,KAAK;AAGb,YAAM,MAAM,MAAM,KAAK,MAAM;AAG7B,SAAG,KAAK,KAAK;AACb,SAAG,KAAK,KAAK;AAGb,YAAM,MAAM,MAAM,KAAK,MAAM;AAAA,IACjC;AAGA,WAAO,kBAAkB;AAGzB,WAAO,kBAAkB;AAAA,EAC7B;AACJ;AAEO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,cAAc,MAAM;AAC1B,QAAM,WAAW,MAAM;AACvB,QAAM,eAAe,MAAM,SAAS;AAEpC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,YAAY,CAAC;AAChC,UAAM,UAAU,SAAS,KAAK,CAAC;AAC/B,UAAM,WAAW,QAAQ;AACzB,UAAM,aAAa,SAAS;AAE5B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,eAAS,OAAO,CAAC,EAAE,gBAAgB,WAAW,OAAO,CAAC,EAAE;AACxD,eAAS,OAAO,CAAC,EAAE,iBAAiB,WAAW,OAAO,CAAC,EAAE;AACzD,eAAS,OAAO,CAAC,EAAE,mBAAmB,WAAW,OAAO,CAAC,EAAE;AAC3D,eAAS,OAAO,CAAC,EAAE,iBAAiB,WAAW,OAAO,CAAC,EAAE;AAAA,IAC7D;AAAA,EACJ;AACJ;;;AC9hBO,SAAS,YAAY,GAC5B;AACI,QAAM,KAAK,EAAE,cAAc,EAAE;AAC7B,QAAM,KAAK,EAAE,cAAc,EAAE;AAE7B,SAAO,KAAO,KAAK;AACvB;AAEO,SAAS,cAAc,GAAG,GACjC;AACI,MAAI,UAAU;AAEd,MAAI,EAAE,cAAc,EAAE,aACtB;AACI,MAAE,cAAc,EAAE;AAClB,cAAU;AAAA,EACd;AAEA,MAAI,EAAE,cAAc,EAAE,aACtB;AACI,MAAE,cAAc,EAAE;AAClB,cAAU;AAAA,EACd;AAEA,MAAI,EAAE,cAAc,EAAE,aACtB;AACI,MAAE,cAAc,EAAE;AAClB,cAAU;AAAA,EACd;AAEA,MAAI,EAAE,cAAc,EAAE,aACtB;AACI,MAAE,cAAc,EAAE;AAClB,cAAU;AAAA,EACd;AAEA,SAAO;AACX;AAEO,SAAS,gBAAgB,GAAG,GACnC;AACI,SAAO,EAAE,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE,eACnB,EAAE,eAAe,EAAE;AAChC;;;ACvCA,IAAM,qBAAqB;AAE3B,SAAS,SAAS,MAClB;AACI,SAAO,KAAK,WAAW;AAC3B;AAkBO,SAAS,uBAChB;AAEI,QAAM,OAAO,IAAI,cAAc;AAC/B,OAAK,OAAO;AAEZ,OAAK,eAAe;AACpB,OAAK,YAAY;AACjB,OAAK,QAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,aAAa,GAAG,MAAM,IAAI,WAAW,CAAC;AAE7E,WAAS,IAAI,GAAG,IAAI,KAAK,eAAe,GAAG,EAAE,GAC7C;AACI,SAAK,MAAM,CAAC,EAAE,cAAc,IAAI;AAChC,SAAK,MAAM,CAAC,EAAE,SAAS;AAAA,EAC3B;AACA,OAAK,MAAM,KAAK,eAAe,CAAC,EAAE,cAAc;AAChD,OAAK,MAAM,KAAK,eAAe,CAAC,EAAE,SAAS;AAC3C,OAAK,WAAW;AAEhB,OAAK,aAAa;AAClB,OAAK,cAAc;AAGnB,OAAK,cAAc;AAGnB,OAAK,kBAAkB;AAEvB,SAAO;AACX;AAWO,SAAS,sBAAsB,MACtC;AAEI,OAAK,QAAQ;AACb,OAAK,cAAc;AAGnB,OAAK,cAAc;AAGvB;AAEA,SAAS,eAAe,MACxB;AACI,MAAI,KAAK,aAAa,eACtB;AACI,UAAM,WAAW,KAAK;AACtB,SAAK,gBAAgB,KAAK,gBAAgB;AAE1C,SAAK,QAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,aAAa,GAAG,MAAM,IAAI,WAAW,CAAC;AAQ7E,SAAK,QAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,aAAa,GAAG,CAAC,GAAG,MAC3D;AACI,UAAI,IAAI,SAAS,QACjB;AACI,eAAO,SAAS,CAAC;AAAA,MACrB,OAEA;AACI,eAAO,IAAI,WAAW;AAAA,MAC1B;AAAA,IACJ,CAAC;AAED,aAAS,IAAI,KAAK,WAAW,IAAI,KAAK,eAAe,GAAG,EAAE,GAC1D;AACI,WAAK,MAAM,CAAC,EAAE,cAAc,IAAI;AAChC,WAAK,MAAM,CAAC,EAAE,SAAS;AAAA,IAC3B;AAEA,SAAK,MAAM,KAAK,eAAe,CAAC,EAAE,cAAc;AAChD,SAAK,MAAM,KAAK,eAAe,CAAC,EAAE,SAAS;AAC3C,SAAK,WAAW,KAAK;AAAA,EACzB;AAEA,QAAM,YAAY,KAAK;AACvB,QAAM,OAAO,KAAK,MAAM,SAAS;AACjC,OAAK,WAAW,KAAK;AACrB,OAAK,MAAM,SAAS,IAAI,IAAI,WAAW;AACvC,IAAE,KAAK;AAEP,SAAO;AACX;AAEA,SAAS,WAAW,MAAM,QAC1B;AACI,OAAK,MAAM,MAAM,EAAE,cAAc,KAAK;AACtC,OAAK,MAAM,MAAM,EAAE,SAAS;AAC5B,OAAK,WAAW;AAChB,IAAE,KAAK;AACX;AAEA,SAAS,kBAAkB,MAAM,MACjC;AACI,QAAM,UAAiB,cAAc,IAAI;AACzC,QAAM,QAAQ,YAAY,IAAI;AAE9B,QAAM,QAAQ,KAAK;AACnB,QAAM,YAAY,KAAK;AAEvB,QAAM,UAAU,MAAM,SAAS,EAAE;AAEjC,MAAI,WAAW,YAAY,OAAO;AAElC,MAAI,aAAa,YAAmB,aAAa,SAAS,IAAI,CAAC;AAC/D,MAAI,gBAAgB;AAEpB,MAAI,cAAc;AAClB,MAAI,WAAW;AAEf,MAAI,QAAQ;AAEZ,SAAO,MAAM,KAAK,EAAE,SAAS,GAC7B;AACI,UAAM,SAAS,MAAM,KAAK,EAAE;AAC5B,UAAM,SAAS,MAAM,KAAK,EAAE;AAE5B,UAAM,OAAO,aAAa;AAE1B,QAAI,OAAO,UACX;AACI,oBAAc;AACd,iBAAW;AAAA,IACf;AAEA,qBAAiB,aAAa;AAE9B,UAAM,QAAQ,MAAM,MAAM,EAAE,WAAW;AACvC,UAAM,QAAQ,MAAM,MAAM,EAAE,WAAW;AAEvC,QAAI,aAAa,OAAO;AACxB,UAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,UAAM,cAAc,YAAmB,aAAa,MAAM,IAAI,CAAC;AAC/D,QAAI,QAAQ;AAEZ,QAAI,OACJ;AACI,YAAM,QAAQ,cAAc;AAE5B,UAAI,QAAQ,UACZ;AACI,sBAAc;AACd,mBAAW;AAAA,MACf;AAAA,IACJ,OAEA;AACI,cAAQ,YAAY,IAAI;AACxB,mBAAa,gBAAgB,cAAc,KAAK,IAAI,QAAQ,OAAO,CAAC;AAAA,IACxE;AAEA,QAAI,aAAa,OAAO;AACxB,UAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,UAAM,cAAc,YAAmB,aAAa,MAAM,IAAI,CAAC;AAC/D,QAAI,QAAQ;AAEZ,QAAI,OACJ;AACI,YAAM,QAAQ,cAAc;AAE5B,UAAI,QAAQ,UACZ;AACI,sBAAc;AACd,mBAAW;AAAA,MACf;AAAA,IACJ,OAEA;AACI,cAAQ,YAAY,IAAI;AACxB,mBAAa,gBAAgB,cAAc,KAAK,IAAI,QAAQ,OAAO,CAAC;AAAA,IACxE;AAEA,QAAI,SAAS,OACb;AACI;AAAA,IACJ;AAEA,QAAI,YAAY,cAAc,YAAY,YAC1C;AACI;AAAA,IACJ;AAEA,QAAI,eAAe,cAAc,CAAC,OAClC;AACI,YAAM,KAAY,MAAa,cAAc,IAAI,GAAG,OAAO;AAC3D,YAAM,KAAY,MAAa,cAAc,IAAI,GAAG,OAAO;AAC3D,mBAAoB,gBAAgB,EAAE;AACtC,mBAAoB,gBAAgB,EAAE;AAAA,IAC1C;AAEA,QAAI,aAAa,cAAc,CAAC,OAChC;AACI,cAAQ;AACR,iBAAW;AACX,mBAAa;AAAA,IACjB,OAEA;AACI,cAAQ;AACR,iBAAW;AACX,mBAAa;AAAA,IACjB;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,IAAM,eAAe;AAAA,EACjB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AACjB;AAIO,SAAS,cAAc,MAAM,IACpC;AACI,UAAQ,OAAO,MAAM,aAAa;AAElC,QAAM,QAAQ,KAAK;AAEnB,QAAM,IAAI,MAAM,EAAE;AAElB,MAAI,EAAE,SAAS,GACf;AACI;AAAA,EACJ;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,EAAE;AACb,UAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,UAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAEhD,QAAM,IAAI,MAAM,EAAE;AAClB,QAAM,IAAI,MAAM,EAAE;AAElB,MAAI,EAAE,WAAW,GACjB;AAEI,YAAQ,OAAO,EAAE,SAAS,CAAC;AAE3B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AACb,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,IAAI,MAAM,EAAE;AAClB,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAGhD,UAAM,WAAW,YAAY,EAAE,IAAI;AAGnC,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,YAAY,MAAM;AAGjC,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,YAAY,MAAM;AAEjC,QAAI,WAAW,UAAU,WAAW,QACpC;AAEI;AAAA,IACJ;AAEA,QAAI,SAAS,QACb;AAEI,QAAE,SAAS;AACX,QAAE,SAAS;AAEX,QAAE,cAAc;AAChB,QAAE,cAAc;AAEhB,QAAE,OAAO;AAET,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,QAAE,WAAW,EAAE,YAAY,EAAE;AAAA,IACjC,OAEA;AAEI,QAAE,SAAS;AACX,QAAE,SAAS;AAEX,QAAE,cAAc;AAChB,QAAE,cAAc;AAEhB,QAAE,OAAO;AAET,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,QAAE,WAAW,EAAE,YAAY,EAAE;AAAA,IACjC;AAAA,EACJ,WACS,EAAE,WAAW,GACtB;AAEI,YAAQ,OAAO,EAAE,SAAS,CAAC;AAE3B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AACb,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,IAAI,MAAM,EAAE;AAClB,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAGhD,UAAM,WAAW,YAAY,EAAE,IAAI;AAGnC,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,YAAY,MAAM;AAGjC,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,YAAY,MAAM;AAEjC,QAAI,WAAW,UAAU,WAAW,QACpC;AAEI;AAAA,IACJ;AAEA,QAAI,SAAS,QACb;AAEI,QAAE,SAAS;AACX,QAAE,SAAS;AAEX,QAAE,cAAc;AAChB,QAAE,cAAc;AAEhB,QAAE,OAAO;AAET,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,QAAE,WAAW,EAAE,YAAY,EAAE;AAAA,IACjC,OAEA;AAEI,QAAE,SAAS;AACX,QAAE,SAAS;AAEX,QAAE,cAAc;AAChB,QAAE,cAAc;AAEhB,QAAE,OAAO;AACT,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,eAAe,EAAE,eAAe,EAAE;AACpC,QAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,QAAE,WAAW,EAAE,YAAY,EAAE;AAAA,IACjC;AAAA,EACJ,OAEA;AACI,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AAEb,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,IAAI,MAAM,EAAE;AAElB,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAChD,YAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,YAAY;AAGhD,UAAM,QAAQ,YAAY,EAAE,IAAI;AAChC,UAAM,QAAQ,YAAY,EAAE,IAAI;AAChC,UAAM,WAAW,QAAQ;AACzB,QAAI,eAAe,aAAa;AAChC,QAAI,WAAW;AAGf,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,QAAQ,YAAY,MAAM;AAEzC,QAAI,SAAS,UACb;AACI,qBAAe,aAAa;AAC5B,iBAAW;AAAA,IACf;AAGA,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,QAAQ,YAAY,MAAM;AAEzC,QAAI,SAAS,UACb;AACI,qBAAe,aAAa;AAC5B,iBAAW;AAAA,IACf;AAGA,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,QAAQ,YAAY,MAAM;AAEzC,QAAI,SAAS,UACb;AACI,qBAAe,aAAa;AAC5B,iBAAW;AAAA,IACf;AAGA,UAAM,SAAgB,aAAa,EAAE,MAAM,EAAE,IAAI;AACjD,UAAM,SAAS,QAAQ,YAAY,MAAM;AAEzC,QAAI,SAAS,UACb;AACI,qBAAe,aAAa;AAAA,IAGhC;AAEA,YAAQ,cACR;AAAA,MACI,KAAK,aAAa;AACd;AAAA,MAEJ,KAAK,aAAa;AACd,UAAE,SAAS;AACX,UAAE,SAAS;AAEX,UAAE,cAAc;AAChB,UAAE,cAAc;AAEhB,UAAE,OAAO;AACT,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,UAAE,WAAW,EAAE,YAAY,EAAE;AAE7B;AAAA,MAEJ,KAAK,aAAa;AACd,UAAE,SAAS;AACX,UAAE,SAAS;AAEX,UAAE,cAAc;AAChB,UAAE,cAAc;AAEhB,UAAE,OAAO;AACT,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,UAAE,WAAW,EAAE,YAAY,EAAE;AAE7B;AAAA,MAEJ,KAAK,aAAa;AACd,UAAE,SAAS;AACX,UAAE,SAAS;AAEX,UAAE,cAAc;AAChB,UAAE,cAAc;AAEhB,UAAE,OAAO;AACT,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,UAAE,WAAW,EAAE,YAAY,EAAE;AAE7B;AAAA,MAEJ,KAAK,aAAa;AACd,UAAE,SAAS;AACX,UAAE,SAAS;AAEX,UAAE,cAAc;AAChB,UAAE,cAAc;AAEhB,UAAE,OAAO;AACT,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,eAAe,EAAE,eAAe,EAAE;AACpC,UAAE,WAAW,EAAE,YAAY,EAAE;AAC7B,UAAE,WAAW,EAAE,YAAY,EAAE;AAE7B;AAAA,MAEJ;AACI,gBAAQ,OAAO,KAAK;AAEpB;AAAA,IACR;AAAA,EACJ;AACJ;AAEO,SAAS,aAAa,MAAM,MAAM,cACzC;AACI,MAAI,KAAK,SAAS,eAClB;AACI,SAAK,OAAO;AACZ,SAAK,MAAM,KAAK,IAAI,EAAE,cAAc;AAEpC;AAAA,EACJ;AAGA,QAAM,WAAW,KAAK,MAAM,IAAI,EAAE;AAClC,QAAM,UAAU,kBAAkB,MAAM,QAAQ;AAGhD,QAAM,YAAY,KAAK,MAAM,OAAO,EAAE;AACtC,QAAM,YAAY,eAAe,IAAI;AAGrC,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,EAAE,cAAc;AAC/B,QAAM,SAAS,EAAE,WAAW;AAC5B,QAAM,SAAS,EAAE,OAAc,aAAa,UAAU,MAAM,OAAO,EAAE,IAAI;AACzE,QAAM,SAAS,EAAE,eAAe,MAAM,IAAI,EAAE,eAAe,MAAM,OAAO,EAAE;AAC1E,QAAM,SAAS,EAAE,SAAS,MAAM,OAAO,EAAE,SAAS;AAElD,MAAI,cAAc,eAClB;AAEI,QAAI,MAAM,SAAS,EAAE,WAAW,SAChC;AACI,YAAM,SAAS,EAAE,SAAS;AAAA,IAC9B,OAEA;AACI,YAAM,SAAS,EAAE,SAAS;AAAA,IAC9B;AACA,UAAM,SAAS,EAAE,SAAS;AAC1B,UAAM,SAAS,EAAE,SAAS;AAC1B,UAAM,OAAO,EAAE,cAAc;AAC7B,UAAM,IAAI,EAAE,cAAc;AAAA,EAC9B,OAEA;AAEI,UAAM,SAAS,EAAE,SAAS;AAC1B,UAAM,SAAS,EAAE,SAAS;AAC1B,UAAM,OAAO,EAAE,cAAc;AAC7B,UAAM,IAAI,EAAE,cAAc;AAC1B,SAAK,OAAO;AAAA,EAChB;AAGA,MAAI,QAAQ,MAAM,IAAI,EAAE;AAExB,SAAO,UAAU,eACjB;AACI,UAAM,SAAS,MAAM,KAAK,EAAE;AAC5B,UAAM,SAAS,MAAM,KAAK,EAAE;AAC5B,YAAQ,OAAO,WAAW,aAAa;AACvC,YAAQ,OAAO,WAAW,aAAa;AACvC,UAAM,KAAK,EAAE,OAAc,aAAa,MAAM,MAAM,EAAE,MAAM,MAAM,MAAM,EAAE,IAAI;AAC9E,UAAM,KAAK,EAAE,eAAe,MAAM,MAAM,EAAE,eAAe,MAAM,MAAM,EAAE;AACvE,UAAM,KAAK,EAAE,SAAS,IAAI,KAAK,IAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,MAAM;AAC7E,UAAM,KAAK,EAAE,WAAW,MAAM,MAAM,EAAE,YAAY,MAAM,MAAM,EAAE;AAEhE,QAAI,cACJ;AACI,oBAAc,MAAM,KAAK;AAAA,IAC7B;AACA,YAAQ,MAAM,KAAK,EAAE;AAAA,EACzB;AACJ;AAEO,SAAS,aAAa,MAAM,MACnC;AACI,MAAI,SAAS,KAAK,MAClB;AACI,SAAK,OAAO;AAEZ;AAAA,EACJ;AAEA,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,IAAI,EAAE;AAC3B,QAAM,cAAc,MAAM,MAAM,EAAE;AAClC,MAAI;AAEJ,MAAI,MAAM,MAAM,EAAE,WAAW,MAC7B;AACI,cAAU,MAAM,MAAM,EAAE;AAAA,EAC5B,OAEA;AACI,cAAU,MAAM,MAAM,EAAE;AAAA,EAC5B;AAEA,MAAI,gBAAgB,eACpB;AAEI,QAAI,MAAM,WAAW,EAAE,WAAW,QAClC;AACI,YAAM,WAAW,EAAE,SAAS;AAAA,IAChC,OAEA;AACI,YAAM,WAAW,EAAE,SAAS;AAAA,IAChC;AACA,UAAM,OAAO,EAAE,cAAc;AAC7B,eAAW,MAAM,MAAM;AAGvB,QAAI,QAAQ;AAEZ,WAAO,UAAU,eACjB;AACI,YAAM,OAAO,MAAM,KAAK;AACxB,YAAM,SAAS,MAAM,KAAK,MAAM;AAChC,YAAM,SAAS,MAAM,KAAK,MAAM;AAEhC,WAAK,OAAc,aAAa,OAAO,MAAM,OAAO,IAAI;AACxD,WAAK,eAAe,OAAO,eAAe,OAAO;AACjD,WAAK,SAAS,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AACvD,cAAQ,KAAK;AAAA,IACjB;AAAA,EACJ,OAEA;AACI,SAAK,OAAO;AACZ,SAAK,MAAM,OAAO,EAAE,cAAc;AAClC,eAAW,MAAM,MAAM;AAAA,EAC3B;AACJ;AAYO,SAAS,0BAA0B,MAAM,MAAM,cAAc,UACpE;AACI,UAAQ,OAAQ,CAAC,UAAS,KAAK,eAAe,KAAK,cAAc,OAAO;AACxE,UAAQ,OAAQ,CAAC,UAAS,KAAK,eAAe,KAAK,cAAc,OAAO;AACxE,UAAQ,OAAQ,CAAC,UAAS,KAAK,eAAe,KAAK,cAAc,OAAO;AACxE,UAAQ,OAAQ,CAAC,UAAS,KAAK,eAAe,KAAK,cAAc,OAAO;AAExE,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,OAAK,OAAO;AACZ,OAAK,WAAW;AAChB,OAAK,eAAe;AACpB,OAAK,SAAS;AAEd,QAAM,eAAe;AACrB,eAAa,MAAM,SAAS,YAAY;AAExC,OAAK,cAAc;AAEnB,SAAO;AACX;AAgBO,SAAS,2BAA2B,MAAM,SACjD;AACI,UAAQ,OAAQ,KAAK,WAAW,UAAU,KAAK,YAAa;AAC5D,UAAQ,OAAQ,SAAU,KAAK,MAAM,OAAO,CAAE,CAAE;AAEhD,eAAa,MAAM,OAAO;AAC1B,aAAW,MAAM,OAAO;AAExB,UAAQ,OAAQ,KAAK,aAAa,CAAE;AACpC,OAAK,cAAc;AACvB;AAWO,SAAS,4BAA4B,MAC5C;AACI,SAAO,KAAK;AAChB;AAiBO,SAAS,wBAAwB,MAAM,SAAS,MACvD;AACI,UAAQ,OAAe,eAAgB,IAAK,CAAE;AAC9C,UAAQ,OAAQ,KAAK,cAAc,KAAK,cAAc,OAAO;AAC7D,UAAQ,OAAQ,KAAK,cAAc,KAAK,cAAc,OAAO;AAC7D,UAAQ,OAAQ,KAAK,WAAW,UAAU,KAAK,YAAa;AAC5D,UAAQ,OAAQ,SAAU,KAAK,MAAM,OAAO,CAAE,CAAE;AAEhD,eAAa,MAAM,OAAO;AAE1B,OAAK,MAAM,OAAO,EAAE,OAAO;AAE3B,QAAM,eAAe;AACrB,eAAa,MAAM,SAAS,YAAY;AAC5C;AAkBO,SAAS,2BAA2B,MAAM,SAAS,MAC1D;AACI,QAAM,QAAQ,KAAK;AAEnB,UAAQ,OAAe,eAAgB,IAAK,CAAE;AAC9C,UAAQ,OAAQ,KAAK,cAAc,KAAK,cAAc,OAAO;AAC7D,UAAQ,OAAQ,KAAK,cAAc,KAAK,cAAc,OAAO;AAC7D,UAAQ,OAAQ,KAAK,WAAW,UAAU,KAAK,YAAa;AAC5D,UAAQ,OAAQ,SAAU,KAAK,MAAM,OAAO,CAAE,CAAE;AAGhD,UAAQ,OAAe,gBAAiB,MAAM,OAAO,EAAE,MAAM,IAAK,KAAK,KAAM;AAE7E,QAAM,OAAO,EAAE,OAAO;AAGtB,MAAI,cAAc,MAAM,OAAO,EAAE;AAEjC,SAAO,gBAAgB,eACvB;AACI,UAAM,UAAU,cAAc,MAAM,WAAW,EAAE,MAAM,IAAI;AAC3D,UAAM,WAAW,EAAE,WAAW;AAC9B,kBAAc,MAAM,WAAW,EAAE;AAEjC,QAAI,CAAC,SACL;AACI;AAAA,IACJ;AAAA,EACJ;AAGA,SAAO,gBAAgB,eACvB;AACI,QAAI,MAAM,WAAW,EAAE,aAAa,MACpC;AAEI;AAAA,IACJ;AAEA,UAAM,WAAW,EAAE,WAAW;AAC9B,kBAAc,MAAM,WAAW,EAAE;AAAA,EACrC;AACJ;AAYO,SAAS,wBAAwB,MACxC;AACI,MAAI,KAAK,SAAS,eAClB;AACI,WAAO;AAAA,EACX;AAEA,SAAO,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC;AAYO,SAAS,2BAA2B,MAC3C;AACI,MAAI,KAAK,SAAS,eAClB;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,KAAK,MAAM,KAAK,IAAI;AACjC,QAAM,WAAW,YAAY,KAAK,IAAI;AAEtC,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,IAAI,KAAK,cAAc,EAAE,GACzC;AACI,UAAM,OAAO,KAAK,MAAM,CAAC;AAEzB,QAAI,KAAK,SAAS,KAAK,SAAS,IAAI,KAAK,MAAM,KAAK,MACpD;AAEI;AAAA,IACJ;AAEA,iBAAa,YAAY,KAAK,IAAI;AAAA,EACtC;AAEA,SAAO,YAAY;AACvB;AA+BO,SAAS,uBAAuB,MACvC;AAEA;AAWO,SAAS,4BAA4B,MAC5C;AACI,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,KAAK,cAAc,EAAE,GACzC;AACI,UAAM,OAAO,KAAK,MAAM,CAAC;AAEzB,QAAI,KAAK,UAAU,GACnB;AACI;AAAA,IACJ;AAEA,YAAQ,OAAO,SAAS,IAAI,KAAK,KAAK;AAEtC,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,KAAK,IAAI,KAAK,MAAM,MAAM,EAAE,SAAS,KAAK,MAAM,MAAM,EAAE,MAAM;AAC9E,iBAAa,KAAK,IAAI,YAAY,OAAO;AAAA,EAC7C;AAEA,SAAO;AACX;AAYO,SAAS,8BAA8B,MAC9C;AACI,QAAM,QAAQ,IAAI,MAAM,KAAK,SAAS;AACtC,MAAI,QAAQ;AAGZ,WAAS,IAAI,GAAG,IAAI,KAAK,cAAc,EAAE,GACzC;AACI,QAAI,KAAK,MAAM,CAAC,EAAE,SAAS,GAC3B;AAEI;AAAA,IACJ;AAEA,QAAI,SAAS,KAAK,MAAM,CAAC,CAAC,GAC1B;AACI,WAAK,MAAM,CAAC,EAAE,cAAc;AAC5B,YAAM,KAAK,IAAI;AACf,QAAE;AAAA,IACN,OAEA;AACI,iBAAW,MAAM,CAAC;AAAA,IACtB;AAAA,EACJ;AAEA,SAAO,QAAQ,GACf;AACI,QAAI,UAAU,OAAO;AACrB,QAAI,OAAO,IACP,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,CAAC,EAAE;AAEnC,eAAS,IAAI,IAAI,GAAG,IAAI,OAAO,EAAE,GACjC;AACI,cAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,CAAC,EAAE;AACnC,cAAM,IAAW,aAAa,OAAO,KAAK;AAC1C,cAAM,OAAO,YAAY,CAAC;AAE1B,YAAI,OAAO,SACX;AACI,iBAAO;AACP,iBAAO;AACP,oBAAU;AAAA,QACd;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,UAAU,MAAM,IAAI;AAC1B,UAAM,UAAU,MAAM,IAAI;AAC1B,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,UAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,UAAM,cAAc,eAAe,IAAI;AACvC,UAAM,SAAS,KAAK,MAAM,WAAW;AACrC,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,OAAc,aAAa,OAAO,MAAM,OAAO,IAAI;AAC1D,WAAO,eAAe,OAAO,eAAe,OAAO;AACnD,WAAO,SAAS,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AACzD,WAAO,cAAc;AAErB,WAAO,cAAc;AACrB,WAAO,cAAc;AAErB,UAAM,IAAI,IAAI,MAAM,QAAQ,CAAC;AAC7B,UAAM,IAAI,IAAI;AACd,MAAE;AAAA,EACN;AAEA,OAAK,OAAO,MAAM,CAAC;AAEnB,yBAAuB,IAAI;AAC/B;AAYO,SAAS,0BAA0B,MAAM,WAChD;AAEI,WAAS,IAAI,GAAG,IAAI,KAAK,cAAc,EAAE,GACzC;AACI,UAAM,IAAI,KAAK,MAAM,CAAC;AACtB,MAAE,KAAK,eAAe,UAAU;AAChC,MAAE,KAAK,eAAe,UAAU;AAChC,MAAE,KAAK,eAAe,UAAU;AAChC,MAAE,KAAK,eAAe,UAAU;AAAA,EACpC;AACJ;AAaO,SAAS,2BAA2B,MAC3C;AACI,QAAM,OAAO,OAAO,KAAK,IAAI,EAAE,SAAS;AAAA,EAC7B,KAAK,eAAe,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,EAAE,SAAS;AAAA,EACxD,KAAK,mBAAmB,IAAI,KAAK,IAAI;AAEhD,SAAO;AACX;AAeO,SAAS,oBAAoB,MAAM,MAAM,UAAU,UAAU,SACpE;AACI,MAAI,KAAK,QAAQ,eACjB;AACI;AAAA,EACJ;AAEA,QAAMC,SAAQ,CAAC;AACf,EAAAA,OAAM,KAAK,KAAK,IAAI;AAEpB,SAAOA,OAAM,SAAS,GACtB;AACI,UAAM,SAASA,OAAM,IAAI;AAEzB,QAAI,UAAU,eACd;AACI;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,SAAK,KAAK,eAAe,cAAc,KAAK,gBAAgB,KAAK,MAAM,IAAI,GAC3E;AAEI,UAAI,KAAK,UAAU,GACnB;AAEI,cAAM,UAAU,SAAS,QAAQ,KAAK,UAAU,OAAO;AAEvD,YAAI,YAAY,OAChB;AACI;AAAA,QACJ;AAAA,MACJ,OAEA;AACI,QAAAA,OAAM,KAAK,KAAK,MAAM;AACtB,QAAAA,OAAM,KAAK,KAAK,MAAM;AAAA,MAC1B;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,IAAM,QAAQ,MAAM,EAAE;AAEf,SAAS,uBAAuB,MAAM,MAAM,SACnD;AACI,MAAI,KAAK,QAAQ,eACjB;AACI;AAAA,EACJ;AAEA,QAAM,KAAK,KAAK,aACZ,KAAK,KAAK;AACd,QAAM,KAAK,KAAK,aACZ,KAAK,KAAK;AACd,QAAM,QAAQ,KAAK;AAEnB,MAAI,aAAa;AACjB,QAAM,YAAY,IAAI,KAAK;AAE3B,MAAI,QAAQ,MAAM;AAElB,SAAO,aAAa,GACpB;AACI,aAAS,MAAM,EAAE,UAAU;AAC3B,WAAO,MAAM,MAAM;AAEnB,QAAI,KAAK,UAAU,GACnB;AACI,UAAI,KAAK;AAET,UAAI,EAAE,cAAc,MAChB,EAAE,cAAc,MAChB,EAAE,cAAc,MAChB,EAAE,cAAc,IACpB;AACI,4BAAoB,QAAQ,KAAK,UAAU,OAAO;AAAA,MACtD;AAAA,IACJ,OAEA;AACI,UAAI,KAAK;AAET,UAAI,EAAE,cAAc,MAChB,EAAE,cAAc,MAChB,EAAE,cAAc,MAChB,EAAE,cAAc,IACpB;AAEI,cAAM,YAAY,IAAI,KAAK;AAC3B,cAAM,YAAY,IAAI,KAAK;AAAA,MAC/B;AAAA,IACJ;AAAA,EACJ;AACJ;AAoBO,SAAS,sBAAsB,MAAM,OAAO,UAAU,UAAU,SACvE;AACI,QAAMC,MAAK,MAAM;AACjB,QAAM,IAAI,MAAM;AAEhB,QAAM,IAAW,YAAY,CAAC;AAG9B,QAAM,IAAW,UAAU,GAAK,CAAC;AACjC,QAAM,QAAe,MAAM,CAAC;AAK5B,MAAI,cAAc,MAAM;AAExB,MAAIC,MAAY,SAASD,KAAI,aAAa,CAAC;AAI3C,QAAM,cAAc,IAAW,OAAO,KAAK,IAAIA,IAAG,GAAGC,IAAG,CAAC,GAAG,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC,GAAG,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC,GAAG,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC,CAAC;AAE5H,QAAMF,SAAQ,CAAC;AACf,EAAAA,OAAM,KAAK,KAAK,IAAI;AAEpB,QAAM,WAAW;AAEjB,SAAOA,OAAM,SAAS,GACtB;AACI,UAAM,SAASA,OAAM,IAAI;AAEzB,QAAI,UAAU,eACd;AACI;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,QAAI,gBAAgB,KAAK,MAAM,WAAW,KAAK,UAAU,KAAK,eAAe,aAAa,GAC1F;AACI;AAAA,IACJ;AAKA,UAAMG,KAAW,cAAc,KAAK,IAAI;AACxC,UAAM,IAAW,eAAe,KAAK,IAAI;AACzC,UAAM,QAAQ,KAAK,IAAW,MAAM,GAAU,MAAMF,KAAIE,EAAC,CAAC,CAAC;AAC3D,UAAM,QAAe,MAAM,OAAO,CAAC;AAEnC,QAAI,QAAQ,OACZ;AACI;AAAA,IACJ;AAEA,QAAI,KAAK,UAAU,GACnB;AACI,eAAS,cAAc;AAEvB,YAAM,QAAQ,SAAS,UAAU,QAAQ,KAAK,UAAU,OAAO;AAE/D,UAAI,SAAS,GACb;AAEI;AAAA,MACJ;AAEA,UAAI,IAAM,SAAS,SAAS,aAC5B;AAEI,sBAAc;AACd,QAAAD,MAAY,SAASD,KAAI,aAAa,CAAC;AACvC,oBAAY,cAAc,KAAK,IAAIA,IAAG,GAAGC,IAAG,CAAC;AAC7C,oBAAY,cAAc,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC;AAC7C,oBAAY,cAAc,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC;AAC7C,oBAAY,cAAc,KAAK,IAAID,IAAG,GAAGC,IAAG,CAAC;AAAA,MACjD;AAAA,IACJ,OAEA;AAGI,MAAAF,OAAM,KAAK,KAAK,MAAM;AACtB,MAAAA,OAAM,KAAK,KAAK,MAAM;AAAA,IAC1B;AAAA,EACJ;AACJ;AAmBO,SAAS,wBAAwB,MAAM,OAAO,UAAU,UAAU,SACzE;AACI,MAAI,MAAM,SAAS,GACnB;AACI;AAAA,EACJ;AAEA,QAAM,aAAa,IAAW,OAAO,MAAM,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;AAErE,WAAS,IAAI,GAAG,IAAI,MAAM,OAAO,EAAE,GACnC;AACI,eAAW,cAAc,KAAK,IAAI,WAAW,aAAa,MAAM,OAAO,CAAC,EAAE,CAAC;AAC3E,eAAW,cAAc,KAAK,IAAI,WAAW,aAAa,MAAM,OAAO,CAAC,EAAE,CAAC;AAC3E,eAAW,cAAc,KAAK,IAAI,WAAW,aAAa,MAAM,OAAO,CAAC,EAAE,CAAC;AAC3E,eAAW,cAAc,KAAK,IAAI,WAAW,aAAa,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,EAC/E;AAKA,aAAW,cAAc,WAAW,cAAc,MAAM;AACxD,aAAW,cAAc,WAAW,cAAc,MAAM;AACxD,aAAW,cAAc,WAAW,cAAc,MAAM;AACxD,aAAW,cAAc,WAAW,cAAc,MAAM;AAExD,QAAMC,MAAY,cAAc,UAAU;AAC1C,QAAM,YAAmB,eAAe,UAAU;AAGlD,QAAM,IAAI,MAAM;AAChB,QAAM,IAAW,UAAU,GAAK,CAAC;AACjC,QAAM,QAAe,MAAM,CAAC;AAK5B,MAAI,cAAc,MAAM;AAGxB,MAAI,IAAW,QAAQ,aAAa,MAAM,WAAW;AAGrD,QAAM,YAAY,IAAW;AAAA,IACzB,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AAAA,IAC7D,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AAAA,IAC7D,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AAAA,IAC7D,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AAAA,EACjE;AAEA,QAAM,WAAW;AAEjB,QAAMD,SAAQ,CAAC;AACf,EAAAA,OAAM,KAAK,KAAK,IAAI;AAEpB,SAAOA,OAAM,SAAS,GACtB;AACI,UAAM,SAASA,OAAM,IAAI;AAEzB,QAAI,UAAU,eACd;AACI;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,QAAI,gBAAgB,KAAK,MAAM,SAAS,KAAK,UAAU,KAAK,eAAe,aAAa,GACxF;AACI;AAAA,IACJ;AAKA,UAAMG,KAAW,cAAc,KAAK,IAAI;AACxC,UAAM,IAAW,MAAa,eAAe,KAAK,IAAI,GAAG,SAAS;AAClE,UAAM,QAAQ,KAAK,IAAW,MAAM,GAAU,MAAMF,KAAIE,EAAC,CAAC,CAAC;AAC3D,UAAM,QAAe,MAAM,OAAO,CAAC;AAEnC,QAAI,QAAQ,OACZ;AACI;AAAA,IACJ;AAEA,QAAI,KAAK,UAAU,GACnB;AACI,eAAS,cAAc;AAEvB,YAAM,QAAQ,SAAS,UAAU,QAAQ,KAAK,UAAU,OAAO;AAE/D,UAAI,SAAS,GACb;AAEI;AAAA,MACJ;AAEA,UAAI,IAAM,SAAS,QAAQ,aAC3B;AAEI,sBAAc;AACd,YAAW,QAAQ,aAAa,MAAM,WAAW;AAIjD,kBAAU,cAAc,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AACrF,kBAAU,cAAc,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AACrF,kBAAU,cAAc,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AACrF,kBAAU,cAAc,KAAK,IAAI,WAAW,aAAa,WAAW,cAAc,EAAE,CAAC;AAAA,MACzF;AAAA,IACJ,OAEA;AAGI,MAAAH,OAAM,KAAK,KAAK,MAAM;AACtB,MAAAA,OAAM,KAAK,KAAK,MAAM;AAAA,IAC1B;AAAA,EACJ;AACJ;AAGA,SAAS,eAAe,SAAS,SAAS,YAAY,UAAU,OAChE;AAEI,MAAI,SAAS,GACb;AACI,WAAO,cAAc,SAAS;AAAA,EAClC;AAGA,MAAI,cAAc,QAAQ,UAAU,EAAE;AACtC,MAAI,cAAc,QAAQ,UAAU,EAAE;AACtC,MAAI,cAAc,QAAQ,UAAU,EAAE;AACtC,MAAI,cAAc,QAAQ,UAAU,EAAE;AAEtC,WAAS,IAAI,aAAa,GAAG,IAAI,UAAU,EAAE,GAC7C;AACI,UAAM,IAAI,QAAQ,CAAC,EAAE;AACrB,UAAM,IAAI,QAAQ,CAAC,EAAE;AAErB,QAAI,IAAI,aAAa;AAAE,oBAAc;AAAA,IAAG,WAC/B,IAAI,aAAa;AAAE,oBAAc;AAAA,IAAG;AAE7C,QAAI,IAAI,aAAa;AAAE,oBAAc;AAAA,IAAG,WAC/B,IAAI,aAAa;AAAE,oBAAc;AAAA,IAAG;AAAA,EACjD;AAGA,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,cAAc;AACzB,QAAM,OAAO,KAAK;AAGlB,MAAI,OAAO;AACX,MAAI,QAAQ,WAAW;AAEvB,MAAI,MACJ;AACI,UAAM,QAAQ,OAAO,cAAc;AAEnC,WAAO,MACP;AACI,aAAO,QAAQ,SAAS,QAAQ,IAAI,EAAE,IAAI,OAAO;AAAE;AAAA,MAAQ;AAE3D,aAAO,QAAQ,SAAS,QAAQ,KAAK,EAAE,IAAI,OAAO;AAAE;AAAA,MAAS;AAE7D,UAAI,QAAQ,OAAO;AAAE;AAAA,MAAO;AAG5B,UAAI,OAAO,QAAQ,IAAI;AACvB,cAAQ,IAAI,IAAI,QAAQ,KAAK;AAC7B,cAAQ,KAAK,IAAI;AAEjB,aAAO,QAAQ,IAAI;AACnB,cAAQ,IAAI,IAAI,QAAQ,KAAK;AAC7B,cAAQ,KAAK,IAAI;AAEjB;AACA;AAAA,IACJ;AAAA,EACJ,OAEA;AACI,UAAM,QAAQ,OAAO,cAAc;AAEnC,WAAO,MACP;AACI,aAAO,QAAQ,SAAS,QAAQ,IAAI,EAAE,IAAI,OAC1C;AACI;AAAA,MACJ;AAEA,aAAO,QAAQ,SAAS,QAAQ,KAAK,EAAE,IAAI,OAC3C;AACI;AAAA,MACJ;AAEA,UAAI,QAAQ,OACZ;AACI;AAAA,MACJ;AAGA,UAAI,OAAO,QAAQ,IAAI;AACvB,cAAQ,IAAI,IAAI,QAAQ,KAAK;AAC7B,cAAQ,KAAK,IAAI;AAEjB,aAAO,QAAQ,IAAI;AACnB,cAAQ,IAAI,IAAI,QAAQ,KAAK;AAC7B,cAAQ,KAAK,IAAI;AAEjB;AACA;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,OAAO,cAAc,OAAO,WAAW,OAAQ,cAAc,SAAS;AACjF;AAEA,SAAS,YAAY,MAAM,WAC3B;AACI,QAAM,EAAE,OAAO,aAAa,YAAY,IAAI;AAE5C,MAAI,cAAc,GAClB;AACI,UAAM,YAAY,CAAC,CAAC,EAAE,cAAc;AAEpC,WAAO,YAAY,CAAC;AAAA,EACxB;AAEA,QAAMA,SAAQ,IAAI,MAAM,kBAAkB;AAC1C,MAAI,MAAM;AAEV,EAAAA,OAAM,CAAC,IAAI;AAAA,IACP,WAAW,eAAe,IAAI;AAAA,IAC9B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,YAAY,eAAe,aAAa,aAAa,GAAG,WAAW,SAAS;AAAA,EAChF;AAEA,SAAO,MACP;AACI,UAAM,OAAOA,OAAM,GAAG;AACtB,SAAK;AAEL,QAAI,KAAK,eAAe,GACxB;AACI,UAAI,QAAQ,GAAG;AAAE;AAAA,MAAO;AAExB,YAAM,aAAaA,OAAM,MAAM,CAAC;AAChC,YAAM,aAAa,MAAM,WAAW,SAAS;AAC7C,YAAM,aAAa,KAAK;AAExB,UAAI,WAAW,eAAe,GAC9B;AACI,mBAAW,SAAS;AAAA,MACxB,OAEA;AACI,mBAAW,SAAS;AAAA,MACxB;AAEA,YAAM,OAAO,MAAM,UAAU;AAC7B,WAAK,cAAc,WAAW;AAE9B,YAAMI,UAAS,MAAM,KAAK,MAAM;AAChC,YAAMC,UAAS,MAAM,KAAK,MAAM;AAEhC,WAAK,OAAc,aAAaD,QAAO,MAAMC,QAAO,IAAI;AACxD,WAAK,SAAS,IAAI,KAAK,IAAID,QAAO,QAAQC,QAAO,MAAM;AACvD,WAAK,eAAeD,QAAO,eAAeC,QAAO;AAEjD;AAAA,IACJ,OAEA;AACI,YAAM,CAAE,YAAY,QAAS,IAAI,KAAK,eAAe,IAC/C,CAAE,KAAK,YAAY,KAAK,UAAW,IACnC,CAAE,KAAK,YAAY,KAAK,QAAS;AAEvC,YAAM,QAAQ,WAAW;AAEzB,UAAI,UAAU,GACd;AACI,cAAM,aAAa,YAAY,UAAU;AACzC,cAAM,OAAO,MAAM,KAAK,SAAS;AAEjC,aAAK,KAAK,eAAe,IAAI,WAAW,QAAQ,IAAI;AAEpD,cAAM,UAAU,EAAE,cAAc,KAAK;AAAA,MACzC,OAEA;AACI,QAAAL,OAAM,EAAE,GAAG,IAAI;AAAA,UACX,WAAW,eAAe,IAAI;AAAA,UAC9B,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA,YAAY;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YAAY;AAAA,YACZ;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,WAAW,MAAMA,OAAM,CAAC,EAAE,SAAS;AACzC,QAAM,SAAS,MAAM,SAAS,MAAM;AACpC,QAAM,SAAS,MAAM,SAAS,MAAM;AAEpC,WAAS,OAAc,aAAa,OAAO,MAAM,OAAO,IAAI;AAC5D,WAAS,SAAS,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AAC3D,WAAS,eAAe,OAAO,eAAe,OAAO;AAErD,SAAOA,OAAM,CAAC,EAAE;AACpB;AAaO,SAAS,sBAAsB,MACtC;AACI,QAAM,aAAa,KAAK;AAExB,MAAI,eAAe,GACnB;AACI,WAAO;AAAA,EACX;AAGA,MAAI,aAAa,KAAK,iBACtB;AACI,UAAM,cAAc,aAAa,KAAK,MAAM,aAAa,CAAC;AAE1D,SAAK,cAAc,MAAM,WAAW;AACpC,SAAK,cAAc,MAAM,WAAW;AACpC,SAAK,kBAAkB;AAAA,EAC3B;AAEA,MAAI,YAAY;AAChB,QAAMA,SAAQ,CAAC;AAEf,MAAI,YAAY,KAAK;AACrB,QAAM,QAAQ,KAAK;AACnB,MAAI,OAAO,MAAM,SAAS;AAI1B,QAAM,cAAc,KAAK;AACzB,QAAM,cAAc,KAAK;AAKzB,SAAO,MACP;AACI,QAAI,KAAK,WAAW,KAAK,KAAK,aAAa,OAC3C;AACI,kBAAY,SAAS,IAAI;AACzB,kBAAY,SAAS,IAAW,cAAc,KAAK,IAAI;AACvD;AAGA,WAAK,cAAc;AAAA,IACvB,OAEA;AACI,YAAM,kBAAkB;AAGxB,MAAAA,OAAM,KAAK,KAAK,MAAM;AAEtB,kBAAY,KAAK;AACjB,aAAO,MAAM,SAAS;AAGtB,iBAAW,MAAM,eAAe;AAEhC;AAAA,IACJ;AAGA,QAAIA,OAAM,WAAW,GACrB;AACI;AAAA,IACJ;AAEA,gBAAYA,OAAM,IAAI;AACtB,WAAO,MAAM,SAAS;AAAA,EAC1B;AAEA,UAAQ,OAAO,aAAa,UAAU;AAEtC,OAAK,OAAO,YAAY,MAAM,SAAS;AAEvC,SAAO;AACX;;;AC5sDO,SAAS,0BAA0B,MAAM,SAChD;AACI,QAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,SAAO,OAAO,KAAK,WAAW;AAClC;AAyBO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,QAAQ,CAAC;AACd,SAAK,OAAO;AACZ,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,cAAc,CAAC;AAGpB,SAAK,cAAc,CAAC;AAGpB,SAAK,kBAAkB;AAAA,EAC3B;AACJ;;;AC5CO,SAAS,QAAQ,OACxB;AAEI,MAAI,UAAU,IACd;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,OAAO,QAAQ,WAAW;AAExC,MAAI,UAAU,GACd;AACI,WAAO,KAAK,MAAM,QAAQ,CAAC,KAAK,IAAI;AAAA,EACxC,OAEA;AACI,UAAM,SAAS,OAAO,SAAS,GAAG;AAElC,WAAO,KAAK,MAAM,SAAS,CAAC,MAAM,IAAI,KAAK;AAAA,EAC/C;AACJ;;;ACLO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AAEI,SAAK,OAAO,IAAI,eAAe;AAG/B,SAAK,SAAS,IAAI,iBAAiB;AAGnC,SAAK,SAAS,IAAI,aAAa;AAI/B,SAAK,WAAW,IAAI,eAAe;AAOnC,SAAK,UAAU,IAAI,cAAc;AAGjC,SAAK,WAAW;AAAA,EAEpB;AACJ;AAEO,SAAS,mBAAmB,OAAO,UAC1C;AACI,UAAQ,OAAO,YAAY,CAAC;AAC5B,MAAI,MAAM,MAAM,eAAe,QAAQ;AACvC,MAAI,OAAO;AACX,MAAI,SAAS;AACb,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,UAAU;AACd,WAAS,MAAM,iBAAiB,QAAQ;AACxC,QAAM,IAAI,YAAY;AACtB,MAAI,WAAW;AACf,QAAM,eAAe,QAAQ,IAAI;AACrC;AAEO,SAAS,gBAAgB,OAAO,UACvC;AACI,UAAQ,OAAO,YAAY,UAAU,mBAAmB;AAGxD,QAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAC3D,QAAM,cAAc,MAAM,eAAe,UAAU,cAAc;AAEjE,QAAM,SAAS,MAAM;AACrB,QAAM,WAAW,MAAM;AAEvB,QAAM,YAAY,IAAI,KAAK;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,UAAM,SAAS,IAAI,KAAK,KAAK,CAAC;AAE9B,UAAM,OAAO,OAAO,OAAO,MAAM;AACjC,YAAQ,OAAO,KAAK,aAAa,QAAQ;AACzC,SAAK,WAAW,UAAU;AAC1B,SAAK,aAAa,SAAS,KAAK;AAEhC,SAAK,YAAY;AAEjB,UAAM,SAAS,aAAa,SAAS,IAAI;AACzC,WAAO,OAAO,QAAQ,MAAM;AAE5B,UAAM,QAAQ,eAAe,SAAS,MAAM;AAC5C,WAAO,OAAO,OAAO,IAAI,YAAY,CAAC;AAGtC,QAAI,aAAa,KAAK;AAEtB,WAAO,eAAe,eACtB;AACI,YAAM,YAAY,aAAa;AAC/B,YAAM,YAAY,cAAc;AAGhC,YAAM,UAAU,SAAS,SAAS;AAElC,mBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,UAAI,QAAQ,aAAa,UAAU,gBACnC;AACI,gBAAQ,OAAO,QAAQ,aAAa,UAAU,eAAe,QAAQ,aAAa,QAAQ;AAE1F;AAAA,MACJ;AAEA,YAAM,aAAa,QAAQ;AAC3B,cAAQ,OAAO,KAAK,cAAc,aAAa,YAAY,SAAS,KAAK;AACzE,YAAM,aAAa,YAAY,SAAS,KAAK,UAAU;AAEvD,cAAQ,QAAQ,QAAQ,QAAQ,eAAe,4BAA4B,KAAK,WAAW,SAAS,eAAe,CAAC;AAEpH,cAAQ,WAAW,UAAU;AAC7B,cAAQ,aAAa,SAAS,SAAS;AACvC,YAAM,kBAAkB,aAAa,SAAS,QAAQ;AACtD,sBAAgB,IAAI,UAAU;AAE9B,YAAM,kBAAkB,gBAAgB,YAAY,UAAU,UAAU;AAExE,UAAI,oBAAoB,eACxB;AACI,cAAM,eAAe,YAAY,SAAS,KAAK,UAAU;AACzD,cAAM,UAAU,aAAa;AAG7B,gBAAQ,OAAO,SAAS,OAAO,EAAE,eAAe,eAAe;AAC/D,iBAAS,OAAO,EAAE,aAAa;AAAA,MACnC;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,eAAe,IAAI,SAAS;AAElC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,IAAI,SAAS,KAAK,CAAC;AACtC,UAAM,UAAU,SAAS,WAAW,SAAS;AAC7C,YAAQ,OAAO,QAAQ,QAAQ,eAAe,sBAAsB;AACpE,YAAQ,OAAO,WAAW,WAAW,kBAAkB,kBAAkB;AACzE,YAAQ,OAAO,WAAW,SAAS,aAAa,CAAC;AACjD,YAAQ,OAAO,QAAQ,aAAa,QAAQ;AAC5C,wBAAoB,OAAO,YAAY,OAAO;AAC9C,YAAQ,WAAW,UAAU;AAAA,EACjC;AAEA,QAAM,SAAS,MAAM;AACrB,QAAM,aAAa,IAAI,OAAO;AAE9B,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,UAAM,WAAW,IAAI,OAAO,KAAK,CAAC;AAClC,UAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,YAAQ,OAAO,MAAM,aAAa,QAAQ;AAC1C,sBAAkB,OAAO,UAAU,KAAK;AACxC,UAAM,WAAW,UAAU;AAAA,EAC/B;AAEA,QAAM,UAAU,MAAM;AACtB,QAAM,cAAc,IAAI,QAAQ;AAEhC,WAAS,IAAI,GAAG,IAAI,aAAa,EAAE,GACnC;AACI,UAAM,YAAY,IAAI,QAAQ,KAAK,CAAC;AAGpC,UAAM,SAAS,QAAQ,UAAU,QAAQ;AACzC,WAAO,WAAW,UAAU;AAC5B,WAAO,aAAa,SAAS,QAAQ;AACrC,UAAM,YAAY,YAAY,SAAS,OAAO;AAC9C,WAAO,OAAO,WAAW,SAAS;AAAA,EACtC;AAEA,qBAAmB,OAAO,QAAQ;AAElC,uBAAqB,KAAK;AAC9B;AAEO,SAAS,iBAAiB,OAAO,UACxC;AAEI,QAAM,SAAS,MAAM,YAAY,QAAQ;AACzC,UAAQ,OAAO,OAAO,aAAa,UAAU,aAAa,qDAAqD,OAAO,QAAQ,EAAE;AAEhI,MAAI,OAAO,wBAAwB,GACnC;AACI;AAAA,EACJ;AAEA,QAAM,aAAa,MAAM;AAEzB,QAAM,aAAa,UAAU,MAAM,eAAe;AAElD,MAAI,eAAe,MAAM,eAAe,QACxC;AACI,UAAM,MAAM,IAAI,YAAY;AAC5B,QAAI,WAAW;AACf,UAAM,eAAe,KAAK,GAAG;AAAA,EACjC;AAEA,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAC3D,UAAQ,OAAO,KAAK,OAAO,cAAc,OAAO,aAAa,SAAS,QAAQ,KAAK;AAEnF,QAAM,WAAW,MAAM,eAAe,UAAU;AAChD,WAAS,WAAW;AACpB,WAAS,OAAO,qBAAqB,OAAO,SAAS;AACrD,WAAS,WAAW,qBAAqB,OAAO,YAAY;AAC5D,WAAS,SAAS,mBAAmB,OAAO,UAAU;AAEtD,QAAM,cAAc,MAAM,eAAe,UAAU,cAAc;AACjE,QAAM,SAAS,MAAM;AACrB,QAAM,WAAW,MAAM;AACvB,MAAI,SAAS,OAAO;AAGpB,SAAO,WAAW,eAClB;AAEI,UAAM,OAAO,OAAO,MAAM;AAC1B,YAAQ,OAAO,KAAK,aAAa,UAAU,WAAW;AACtD,YAAQ,OAAO,KAAK,aAAa,QAAQ;AAEzC,QAAI,KAAK,kBAAkB,eAC3B;AAEI,cAAQ,OAAO,WAAW,KAAK,aAAa,EAAE,OAAO,SAAS,MAAM,MAAM;AAC1E,cAAQ,OAAO,WAAW,KAAK,aAAa,EAAE,OAAO,aAAa,KAAK,QAAQ;AAC/E,iBAAW,KAAK,aAAa,EAAE,aAAa;AAC5C,WAAK,gBAAgB;AAAA,IACzB;AAEA,UAAM,iBAAiB,KAAK;AAC5B,YAAQ,OAAO,KAAK,kBAAkB,iBAAiB,SAAS,KAAK,KAAK;AAE1E,UAAM,WAAW,SAAS,KAAK,KAAK,cAAc;AAElD,UAAM,iBAAiB,SAAS,KAAK;AACrC,UAAM,eAAe,aAAa,SAAS,IAAI;AAC/C,aAAS,OAAO,YAAY;AAM5B,UAAM,aAAa,gBAAgB,SAAS,MAAM,cAAc;AAKhE,YAAQ,OAAO,MAAM,eAAe,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,aAAa,MAAM,qBAAqB;AAE5F,QAAI,eAAe,eACnB;AACI,YAAM,WAAW,SAAS,KAAK,KAAK,cAAc;AAClD,YAAM,UAAU,SAAS;AAGzB,YAAM,YAAY,OAAO,OAAO;AAChC,cAAQ,OAAO,UAAU,eAAe,UAAU;AAClD,gBAAU,aAAa;AAAA,IAC3B;AAEA,sBAAkB,SAAS,QAAQ,cAAc;AAEjD,SAAK,WAAW;AAChB,SAAK,aAAa;AAElB,QAAI,aAAa,KAAK;AAEtB,WAAO,eAAe,eACtB;AACI,YAAMM,aAAY,cAAc;AAChC,YAAM,YAAY,aAAa;AAG/B,YAAM,UAAU,SAASA,UAAS;AAElC,cAAQ,OAAO,QAAQ,aAAa,UAAU,eAAe,QAAQ,aAAa,UAAU,cAAc;AAC1G,mBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,UAAI,QAAQ,aAAa,UAAU,gBACnC;AACI;AAAA,MACJ;AAEA,UAAI,QAAQ,eAAe,eAC3B;AACI,gBAAQ,QAAQ,QAAQ,QAAQ,eAAe,4BAA4B,CAAC;AAE5E;AAAA,MACJ;AAEA,YAAM,iBAAiB,YAAY;AACnC,YAAM,cAAc,QAAQ,MAAM,cAAc,EAAE;AAGlD,YAAM,YAAY,OAAO,WAAW;AAEpC,UAAI,UAAU,aAAa,UAAU,aACrC;AACI;AAAA,MACJ;AAEA,YAAM,aAAa,QAAQ;AAC3B,cAAQ,OAAO,KAAK,cAAc,aAAa,SAAS,SAAS,KAAK;AACtE,YAAM,aAAa,SAAS,SAAS,KAAK,UAAU;AAEpD,cAAQ,OAAO,WAAW,SAAS,eAAe,CAAC;AACnD,cAAQ,QAAQ,QAAQ,QAAQ,eAAe,4BAA4B,MAAM,QAAQ,QAAQ,eAAe,0BAA0B,CAAC;AAE3I,cAAQ,WAAW,UAAU;AAC7B,cAAQ,aAAa,YAAY,SAAS;AAC1C,YAAM,qBAAqB,aAAa,YAAY,QAAQ;AAC5D,yBAAmB,IAAI,UAAU;AAEjC,YAAM,oBAAoB,gBAAgB,SAAS,UAAU,UAAU;AAEvE,UAAI,sBAAsB,eAC1B;AACI,cAAM,kBAAkB,SAAS,SAAS,KAAK,UAAU;AACzD,cAAM,UAAU,gBAAgB;AAGhC,gBAAQ,OAAO,SAAS,OAAO,EAAE,eAAe,iBAAiB;AACjE,iBAAS,OAAO,EAAE,aAAa;AAAA,MACnC;AAAA,IACJ;AAEA,aAAS,KAAK;AAAA,EAClB;AAEA,MAAI,YAAY,OAAO;AAEvB,SAAO,cAAc,eACrB;AAEI,UAAM,UAAU,SAAS,SAAS;AAClC,YAAQ,OAAO,QAAQ,aAAa,UAAU,WAAW;AACzD,YAAQ,OAAO,QAAQ,aAAa,QAAQ;AAC5C,UAAM,aAAa,QAAQ;AAC3B,YAAQ,OAAO,KAAK,cAAc,aAAa,kBAAkB;AAEjE,UAAM,QAAQ,MAAM,gBAAgB,OAAO,UAAU;AAErD,QAAI,eAAe,kBACnB;AACI,iBAAW,MAAM,SAAS,QAAQ,MAAM,CAAC,EAAE,MAAM;AACjD,iBAAW,MAAM,SAAS,QAAQ,MAAM,CAAC,EAAE,MAAM;AAAA,IACrD;AAEA,UAAM,oBAAoB,QAAQ;AAClC,YAAQ,OAAO,KAAK,qBAAqB,oBAAoB,MAAM,SAAS,KAAK;AACjF,UAAM,kBAAkB,MAAM,SAAS,KAAK,iBAAiB;AAE7D,UAAM,oBAAoB,SAAS,SAAS;AAC5C,UAAM,kBAAkB,aAAa,SAAS,QAAQ;AACtD,oBAAgB,IAAI,eAAe;AAEnC,UAAM,aAAa,gBAAgB,MAAM,UAAU,iBAAiB;AAEpE,QAAI,eAAe,eACnB;AACI,YAAM,kBAAkB,MAAM,SAAS,KAAK,iBAAiB;AAC7D,YAAM,UAAU,gBAAgB;AAGhC,YAAM,eAAe,SAAS,OAAO;AACrC,cAAQ,OAAO,aAAa,eAAe,UAAU;AACrD,mBAAa,aAAa;AAAA,IAC9B;AAEA,YAAQ,WAAW;AACnB,YAAQ,aAAa;AACrB,YAAQ,aAAa;AAErB,gBAAY,QAAQ;AAAA,EACxB;AAEA,QAAM,SAAS,MAAM;AACrB,MAAI,UAAU,OAAO;AAErB,SAAO,YAAY,eACnB;AAEI,UAAM,QAAQ,OAAO,OAAO;AAC5B,YAAQ,OAAO,MAAM,aAAa,UAAU,WAAW;AACvD,YAAQ,OAAO,MAAM,aAAa,QAAQ;AAC1C,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,MAAM;AAEzB,YAAQ,OAAO,KAAK,cAAc,aAAa,kBAAkB;AAEjE,UAAM,QAAQ,MAAM,gBAAgB,OAAO,UAAU;AAErD,YAAQ,OAAO,KAAK,cAAc,aAAa,MAAM,OAAO,KAAK;AACjE,UAAM,gBAAgB,MAAM,OAAO,KAAK,UAAU;AAElD,QAAI,eAAe,kBACnB;AACI,iBAAW,MAAM,SAAS,MAAM,MAAM,CAAC,EAAE,MAAM;AAC/C,iBAAW,MAAM,SAAS,MAAM,MAAM,CAAC,EAAE,MAAM;AAAA,IACnD;AAEA,UAAM,kBAAkB,SAAS,OAAO;AACxC,UAAM,gBAAgB,WAAW,SAAS,MAAM;AAChD,kBAAc,OAAO,aAAa;AAElC,UAAM,aAAa,cAAc,MAAM,QAAQ,UAAU;AAEzD,QAAI,eAAe,eACnB;AACI,YAAM,gBAAgB,MAAM,OAAO,KAAK,UAAU;AAClD,YAAM,UAAU,cAAc;AAG9B,YAAM,aAAa,OAAO,OAAO;AACjC,cAAQ,OAAO,WAAW,eAAe,UAAU;AACnD,iBAAW,aAAa;AAAA,IAC5B;AAEA,UAAM,WAAW;AACjB,UAAM,aAAa;AACnB,UAAM,aAAa;AAEnB,cAAU,MAAM;AAAA,EACpB;AAEA,UAAQ,OAAO,OAAO,aAAa,UAAU,WAAW;AAExD,QAAM,cAAc,OAAO;AAC3B,QAAM,cAAc,YAAY,SAAS,OAAO;AAChD,cAAY,WAAW;AAEvB,QAAM,mBAAmB,eAAe,SAAS,SAAS,WAAW;AAErE,MAAI,qBAAqB,eACzB;AACI,UAAM,iBAAiB,SAAS,QAAQ,KAAK,WAAW;AACxD,UAAM,gBAAgB,eAAe;AAGrC,UAAM,cAAc,MAAM,YAAY,aAAa;AACnD,YAAQ,OAAO,YAAY,eAAe,gBAAgB;AAC1D,gBAAY,aAAa;AAAA,EAC7B;AAEA,SAAO,WAAW;AAClB,SAAO,aAAa;AAEpB,uBAAqB,KAAK;AAC9B;AAEO,SAAS,kBAAkB,OAAO,QAAQ,QACjD;AACI,UAAQ,OAAO,UAAU,UAAU,mBAAmB;AACtD,UAAQ,OAAO,UAAU,UAAU,mBAAmB;AAItD,MAAI,OAAO,MAAM,eAAe,MAAM;AACtC,MAAI,OAAO,MAAM,eAAe,MAAM;AAEtC,MAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,OAChC;AACI,KAAE,MAAM,IAAK,IAAI,CAAE,MAAM,IAAK;AAC9B,KAAE,QAAQ,MAAO,IAAI,CAAE,QAAQ,MAAO;AAAA,EAC1C;AAEA,QAAM,SAAS,MAAM;AACrB,QAAM,YAAY,KAAK,KAAK;AAE5B,WAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,UAAM,SAAS,KAAK,KAAK,KAAK,CAAC;AAE/B,UAAM,OAAO,OAAO,OAAO,MAAM;AACjC,YAAQ,OAAO,KAAK,aAAa,MAAM;AACvC,SAAK,WAAW;AAChB,SAAK,aAAa,KAAK,KAAK;AAE5B,UAAM,SAAS,aAAa,KAAK,IAAI;AACrC,WAAO,OAAO,QAAQ,MAAM;AAAA,EAChC;AAEA,QAAM,WAAW,MAAM;AACvB,QAAM,eAAe,KAAK,SAAS;AAEnC,WAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAM,aAAa,KAAK,SAAS,KAAK,CAAC;AAEvC,UAAM,UAAU,SAAS,WAAW,SAAS;AAC7C,YAAQ,OAAO,QAAQ,aAAa,MAAM;AAC1C,YAAQ,WAAW;AACnB,YAAQ,aAAa,KAAK,SAAS;AAEnC,UAAM,aAAa,aAAa,KAAK,QAAQ;AAC7C,eAAW,IAAI,UAAU;AAAA,EAC7B;AAEA,QAAM,SAAS,MAAM;AACrB,QAAM,aAAa,KAAK,OAAO;AAE/B,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,UAAM,WAAW,KAAK,OAAO,KAAK,CAAC;AAEnC,UAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,YAAQ,OAAO,MAAM,aAAa,MAAM;AACxC,UAAM,WAAW;AACjB,UAAM,aAAa,KAAK,OAAO;AAE/B,UAAM,WAAW,WAAW,KAAK,MAAM;AACvC,WAAO,OAAO,UAAU,QAAQ;AAAA,EACpC;AAEA,QAAM,UAAU,MAAM;AACtB,QAAM,cAAc,KAAK,QAAQ;AAEjC,WAAS,IAAI,GAAG,IAAI,aAAa,EAAE,GACnC;AACI,UAAM,YAAY,KAAK,QAAQ,KAAK,CAAC;AACrC,UAAM,WAAW,UAAU;AAG3B,UAAM,SAAS,QAAQ,QAAQ;AAC/B,WAAO,WAAW;AAClB,WAAO,aAAa,KAAK,QAAQ;AAEjC,UAAM,YAAY,YAAY,KAAK,OAAO;AAC1C,WAAO,OAAO,WAAW,SAAS;AAAA,EACtC;AAEA,qBAAmB,OAAO,MAAM;AAEhC,uBAAqB,KAAK;AAC9B;AAEO,SAAS,eAAe,OAAO,WAAW,WAAW,MAC5D;AACI,UAAQ,OAAO,cAAc,SAAS;AAEtC,QAAM,cAAc,KAAK;AACzB,UAAQ,OAAO,KAAK,eAAe,eAAe,UAAU,KAAK,KAAK;AACtE,QAAM,YAAY,UAAU,KAAK,KAAK,WAAW;AAEjD,QAAM,cAAc,UAAU,KAAK;AACnC,QAAM,YAAY,aAAa,UAAU,IAAI;AAC7C,SAAO,OAAO,WAAW,SAAS;AAElC,QAAM,aAAa,gBAAgB,UAAU,MAAM,WAAW;AAE9D,MAAI,eAAe,eACnB;AACI,UAAM,WAAW,UAAU,KAAK,KAAK,WAAW;AAChD,UAAM,UAAU,SAAS;AACzB,UAAM,YAAY,MAAM,UAAU,OAAO;AACzC,YAAQ,OAAO,UAAU,eAAe,UAAU;AAClD,cAAU,aAAa;AAAA,EAC3B;AAEA,MAAI,UAAU,aAAa,UAAU,aACrC;AACI,sBAAkB,UAAU,QAAQ,WAAW;AAAA,EACnD,WACS,UAAU,aAAa,UAAU,aAC1C;AACI,UAAM,QAAQ,eAAe,UAAU,MAAM;AAC7C,WAAO,OAAO,OAAO,IAAI,YAAY,CAAC;AAAA,EAC1C;AAEA,OAAK,WAAW,UAAU;AAC1B,OAAK,aAAa;AACtB;AAEO,SAAS,gBAAgB,OAAO,WAAW,WAAW,OAC7D;AACI,UAAQ,OAAO,cAAc,SAAS;AAEtC,QAAM,aAAa,MAAM;AACzB,QAAM,aAAa,MAAM;AAEzB,MAAI;AAEJ,MAAI,UAAU,aAAa,UAAU,aACrC;AACI,YAAQ,OAAO,KAAK,cAAc,aAAa,kBAAkB;AACjE,UAAM,QAAQ,MAAM,gBAAgB,OAAO,UAAU;AAErD,YAAQ,OAAO,KAAK,cAAc,aAAa,MAAM,OAAO,KAAK;AACjE,gBAAY,MAAM,OAAO,KAAK,UAAU;AAAA,EAC5C,OAEA;AACI,YAAQ,OAAO,eAAe,aAAa;AAC3C,YAAQ,OAAO,KAAK,cAAc,aAAa,UAAU,OAAO,KAAK;AACrE,gBAAY,UAAU,OAAO,KAAK,UAAU;AAAA,EAChD;AAEA,MAAI,UAAU,aAAa,UAAU,aACrC;AACI,sBAAkB,OAAO,WAAW,KAAK;AACzC,UAAM,WAAW,UAAU;AAAA,EAC/B,OAEA;AACI,UAAM,WAAW,UAAU;AAC3B,UAAM,aAAa,UAAU,OAAO;AACpC,UAAM,aAAa;AAEnB,UAAM,YAAY,WAAW,UAAU,MAAM;AAC7C,WAAO,OAAO,WAAW,SAAS;AAAA,EACtC;AAEA,MAAI,UAAU,aAAa,UAAU,aACrC;AACI,2BAAuB,OAAO,MAAM,MAAM,CAAC,EAAE,QAAQ,MAAM,MAAM,CAAC,EAAE,QAAQ,YAAY,UAAU;AAAA,EACtG,OAEA;AACI,UAAM,aAAa,cAAc,UAAU,QAAQ,UAAU;AAE7D,QAAI,eAAe,eACnB;AACI,YAAM,gBAAgB,UAAU,OAAO,KAAK,UAAU;AACtD,YAAM,UAAU,cAAc;AAG9B,YAAM,aAAa,MAAM,WAAW,OAAO;AAC3C,iBAAW,aAAa;AAAA,IAC5B;AAAA,EACJ;AACJ;;;ACpmBO,IAAM,oBAAoB;AAAA,EAC7B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,6BAA6B;AAAA,EAC7B,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,4BAA4B;AAAA,EAC5B,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,uBAAuB;AAC3B;AAEO,IAAM,oBAAoB;AAAA,EAC7B,cAAc;AAAA,EACd,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,sBAAsB;AAC1B;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EAErB;AACJ;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AAAA,EAE3B;AACJ;AAEO,IAAM,kBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU,IAAI,cAAc;AACjC,SAAK,cAAc;AACnB,SAAK,WAAW;AAAA,EAEpB;AACJ;AAEO,IAAM,aAAN,MAAM,YACb;AAAA,EACI,YAAY,WAAW,GAAG,YAAY,GAAG,eAAe,GACxD;AACI,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,eAAe;AAAA,EACxB;AAAA,EAEA,QACA;AACI,WAAO,IAAI,YAAW,KAAK,UAAU,KAAK,WAAW,KAAK,YAAY;AAAA,EAC1E;AACJ;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,KAAK;AACV,SAAK,SAAS;AACd,SAAK,IAAI;AACT,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,gBAAgB,IAAI,WAAW,GAAG,GAAG,CAAC;AAC3C,SAAK,kBAAkB,IAAI,WAAW,GAAG,GAAG,CAAC;AAC7C,SAAK,iBAAiB,IAAI,WAAW,GAAG,GAAG,CAAC;AAC5C,SAAK,uBAAuB;AAC5B,SAAK,oBAAoB;AACzB,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,iBAAiB;AACtB,SAAK,qBAAqB;AAC1B,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,kBAAkB;AACvB,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,yBAAyB;AAC9B,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,SAAK,qBAAqB;AAC1B,SAAK,iBAAiB;AAAA,EAE1B;AACJ;AAEO,SAAS,WAAW,OAAO,MAAM,GACxC;AACI,MAAI,UAAU,GACd;AACI,WAAO,IAAI,WAAW,GAAK,GAAK,CAAG;AAAA,EACvC;AAEA,QAAM,QAAQ,IAAM,QAAQ;AAC5B,QAAM,KAAK,IAAM,OAAO,IAAI;AAC5B,QAAM,KAAK,IAAI,QAAQ;AACvB,QAAM,KAAK,KAAO,IAAM;AAExB,SAAO,IAAI,WAAW,QAAQ,IAAI,KAAK,IAAI,EAAE;AACjD;AAIA,SAAS,0BAA0B,YAAY,UAAU,SACzD;AACI,QAAM,SAAS,QAAQ;AACvB,QAAM,OAAO,QAAQ;AAErB,QAAM,UAAU,QAAQ,MAAM;AAC9B,QAAM,IAAI,QAAQ;AAClB,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,kBAAyB,kBAAkB,QAAQ;AACzD,QAAM,wBAAwB,iBAAiB;AAC/C,QAAM,yBAAyB,kBAAkB;AAEjD,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,OAAO,CAAC;AAEtB,UAAM,IAAI,MAAM;AAChB,QAAI,IAAI,MAAM;AAUd,UAAM,gBAAgB,KAAO,IAAM,IAAI,IAAI;AAC3C,UAAM,iBAAiB,KAAO,IAAM,IAAI,IAAI;AAG5C,UAAM,IAAI,IAAI,OAAO,IAAI;AACzB,UAAM,KAAK,IAAI,IAAI;AACnB,UAAM,OAAO,MAAM,IAAI,MAAM,IAAI,IAAI,QAAQ;AAC7C,UAAM,OAAO,MAAM,IAAI,MAAM,IAAI,IAAI,QAAQ;AAC7C,UAAM,uBAAuB,IAAI,IAAI,aAAa,IAAI;AAGtD,MAAE,IAAI,OAAO,gBAAgB,EAAE;AAC/B,MAAE,IAAI,OAAO,gBAAgB,EAAE;AAC/B,QAAI,uBAAuB,iBAAiB;AAI5C,UAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAE9B,QAAI,IAAI,uBACR;AACI,YAAM,QAAQ,iBAAiB,KAAK,KAAK,CAAC;AAE1C,QAAE,KAAK;AACP,QAAE,KAAK;AACP,UAAI,gBAAgB;AAAA,IACxB;AAGA,QAAI,IAAI,IAAI,0BAA0B,IAAI,sBAAsB,OAChE;AACI,YAAM,QAAQ,kBAAkB,KAAK,IAAI,CAAC;AAC1C,WAAK;AACL,UAAI,gBAAgB;AAAA,IACxB;AAEA,UAAM,iBAAiB;AACvB,UAAM,kBAAkB;AAAA,EAC5B;AACJ;AAgBA,SAAS,yBAAyB,YAAY,UAAU,SACxD;AACI,QAAM,SAAS,QAAQ;AACvB,QAAM,IAAI,QAAQ;AAElB,UAAQ,OAAO,cAAc,QAAQ;AAErC,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,QAAQ,OAAO,CAAC;AAGtB,2BAAuB,MAAM,eAAe,IAAI,MAAM,iBAAiB,MAAM,aAAa;AAG1F,UAAM,cAAc,IAAI,MAAM,cAAc,IAAI,IAAI,MAAM,eAAe;AACzE,UAAM,cAAc,IAAI,MAAM,cAAc,IAAI,IAAI,MAAM,eAAe;AACzE,YAAQ,OAAO,MAAM,iBAAiB,IAAI;AAAA,EAC9C;AACJ;AAEA,SAAS,qBAAqB,YAAY,UAAU,aAAa,SACjE;AACI,QAAM,cAAc;AACpB,QAAM,QAAQ,YAAY;AAC1B,QAAM,cAAc,MAAM;AAC1B,QAAM,SAAS,YAAY;AAC3B,QAAM,OAAO,YAAY;AACzB,QAAM,SAAS,MAAM;AACrB,QAAM,WAAW,YAAY;AAC7B,QAAM,cAAc,YAAY;AAEhC,QAAM,UAAU,MAAM;AACtB,QAAM,aAAa,MAAM;AAEzB,QAAM,UAAU,MAAM;AAEtB,QAAM,oBAAoB,MAAM,iBAAiB,WAAW,EAAE;AAC9D,QAAM,oBAAoB,MAAM,iBAAiB,WAAW,EAAE;AAC9D,QAAM,cAAc,MAAM,iBAAiB,WAAW;AAEtD,QAAM,mBAAmB,MAAM;AAE/B,QAAM,sBAA6B;AACnC,QAAM,aAAoB;AAE1B,UAAQ,OAAO,cAAc,QAAQ;AAErC,WAAS,WAAW,YAAY,WAAW,UAAU,EAAE,UACvD;AACI,UAAM,QAAQ,OAAO,QAAQ;AAC7B,UAAM,MAAM,KAAK,QAAQ;AAEzB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI,MAAM;AAEhB,YAAQ,OAAO,UAAU,EAAE,CAAC,KAAK,UAAU,EAAE,CAAC,CAAC;AAC/C,YAAQ,OAAO,OAAO,SAAS,CAAC,CAAC;AACjC,QAAI,OAAO,KAAK,MAAM,cAAc;AACpC,QAAI,OAAO,KAAK,MAAM,cAAc;AAEpC,UAAMC,KAAI,UAAU,MAAM,eAAe,IAAI,UAAU,CAAC;AACxD,UAAM,IAAI,UAAU,MAAM,eAAe,IAAI,UAAU,CAAC;AACxD,UAAM,KAAK,YAAYA,IAAG,CAAC;AAI3B,QAAI,UAAU,IAAI,IAAI,MAAM,KAAKA,IAAG,KAAK,CAAC;AAE1C,UAAM,cAAc,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI;AAEpD,UAAM,mBAAmB,SAAS,MAAM,aAAa,IAAI,KAAK,IAAI,MAAM,cAAc,CAAC,IAAI,IAAI;AAE/F,UAAM,sBAAsB;AAE5B,UAAM,gBAAgB,KAAK,IAAI,aAAa,sBAAsB,cAAc,gBAAgB;AAEhG,UAAM,cAAc,IAAI;AACxB,UAAM,cAAc,IAAI;AACxB,UAAM,cAAc,IAAI;AACxB,UAAM,cAAc,IAAI;AAExB,QAAI,UAAU,EAAE,IAAI,IAAI,OAAO,KAAK,IAAI,UAAU,EAAE,IAAI,IAAI,YAAY,IAAI,IAAI,UAAU,EAAE,IAAI,IAAI,YAAY;AAChH,QAAI,UAAU,EAAE,IAAI,IAAI,OAAO,KAAK,IAAI,UAAU,EAAE,IAAI,IAAI,YAAY,IAAI,IAAI,UAAU,EAAE,IAAI,IAAI,YAAY;AAEhH,UAAM,OAAO,OAAO,IAAI,MAAM;AAC9B,SAAK,gBAAgB;AACrB,eAAW,QAAQ,EAAE,YAAY,IAAI;AACrC,eAAW,QAAQ,EAAE,SAAS,IAAI,SAAS,IAAI,SAAS,GAAG,SAAS,KAAK,QAAQ;AACjF,eAAW,QAAQ,EAAE,WAAW,KAAK;AACrC,eAAW,QAAQ,EAAE,aAAa;AAElC,QAAI,MAAM,IAAI;AACd,QAAI,MAAM,IAAI;AACd,QAAI,SAAS;AAEb,SAAK,gBAAgB,IAAI;AACzB,QAAI,gBAAgB;AAEpB,QAAI,SAAS;AAEb,QAAI,gBAAgB,SAAS,KAAK,gBAAgB,SAAS,gBAAgB,KAAK,gBAChF;AACI,WAAK,YAAY;AAEjB,YAAM,eAAe;AAErB,UAAI,KAAK,SAAS,WAAW,kBAAkB,oBAAoB,cAAc,WAAW,eAAe,IAAI,WAC/G;AACI,YAAI,IAAI,UACR;AACI,sBAAY;AACZ,sBAAY,aAAa,YAAY,kBAAkB,CAAC,IAAI;AAAA,QAChE,OAEA;AACI,sBAAY;AACZ,sBAAY,WAAW,YAAY,gBAAgB,CAAC,IAAI;AAAA,QAC5D;AAEA,YAAI,SAAS;AAAA,MACjB,OAEA;AACI,YAAI,WAAW,IAAI,OAAO;AAC1B,YAAI,WAAW,IAAI,OAAO;AAC1B,YAAI,UAAU,IAAI,IAAI,UAAU,EAAE;AAClC,YAAI,UAAU,IAAI,IAAI,UAAU,EAAE;AAAA,MACtC;AAAA,IACJ,OAEA;AAEI,UAAI,WAAW,IAAI,OAAO;AAC1B,UAAI,WAAW,IAAI,OAAO;AAC1B,UAAI,UAAU,IAAI,IAAI,UAAU,EAAE;AAClC,UAAI,UAAU,IAAI,IAAI,UAAU,EAAE;AAClC,WAAK,aAAa;AAAA,IACtB;AAGA,UAAM,SAAS,QAAQ,KAAK,QAAQ;AAEpC,QAAI,KAAK,YAAmB,gBAC5B;AACI,YAAM,cAAc,OAAO;AAC3B,MAAS,SAAS,mBAAmB,WAAW;AAAA,IACpD,WACS,OAAO,wBAAwB,GACxC;AACI,UAAI,KAAK,YAAY,YAAY,gBACjC;AACI,oBAAY,gBAAgB,KAAK;AACjC,oBAAY,iBAAiB,KAAK;AAAA,MACtC;AAAA,IACJ;AAEA,UAAM,YAAY,IAAI;AACtB,UAAM,SAAS,IAAI;AACnB,QAAI,UAAU,KAAK;AAEnB,WAAO,YAAmB,eAC1B;AACI,YAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,cAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,UAAI,QACJ;AACI,cAAM,SAAS;AACf,QAAS,SAAS,mBAAmB,QAAQ;AAAA,MACjD,OAEA;AACI,cAAM,OAAe,mBAAmB,OAAO,SAAS;AACxD,aAAK,eAAe;AACpB,aAAK,eAAe;AACpB,aAAK,eAAe;AACpB,aAAK,eAAe;AACpB,cAAM,OAAO;AAEb,gBAAQ,OAAO,MAAM,iBAAiB,KAAK;AAE3C,YAAI,gBAAgB,MAAM,SAAS,IAAI,MAAM,OAC7C;AACI,gBAAM,UAAU,IAAI;AAAA,YAAO,KAAK,cAAc;AAAA,YAAY,KAAK,cAAc;AAAA,YACzE,KAAK,cAAc;AAAA,YAAY,KAAK,cAAc;AAAA,UAAU;AAChE,gBAAM,UAAU;AAEhB,gBAAM,eAAe;AAErB,UAAS,SAAS,mBAAmB,QAAQ;AAAA,QACjD;AAAA,MACJ;AAEA,gBAAU,MAAM;AAAA,IACpB;AAAA,EACJ;AACJ;AAEA,SAAS,eAAe,OAAO,SAAS,OACxC;AACI,QAAM,YAAY,MAAM;AACxB,QAAM,aAAa,MAAM;AACzB,QAAM,WAAW,aAAa,MAAM;AAEpC,MAAI,cAAc,kBAAkB,6BACpC;AACI,8BAA0B,YAAY,UAAU,OAAO;AAAA,EAC3D,WACS,cAAc,kBAAkB,4BACzC;AACI,6BAAyB,YAAY,UAAU,OAAO;AAAA,EAC1D,OAEA;AAeI,YAAQ,KAAK,6BAA6B,SAAS;AAAA,EACvD;AAIJ;AAEA,SAAS,mBAAmB,OAAO,SACnC;AAEI,QAAM,aAAa,MAAM;AAEzB,WAAS,IAAI,GAAG,IAAI,YAAY,KAChC;AACI,mBAAe,OAAO,SAAS,MAAM,OAAO,CAAC,CAAC;AAAA,EAClD;AACJ;AAEO,SAAS,aAAa,eAC7B;AACI,QAAM,cAAc,cAAc;AAClC,QAAM,UAAU,cAAc;AAC9B,QAAM,mBAAmB,QAAQ;AACjC,QAAM,SAAS,QAAQ;AAEvB,MAAI,gBAAgB,GACpB;AAEI,QAAI,aAAa;AAEjB,uBAAmB,OAAO,UAAU,GAAG,OAAO;AAC9C,kBAAc;AAMd,uBAAmB,OAAO,UAAU,GAAG,OAAO;AAC9C,kBAAc;AAOd,IAAQ,wBAAwB,OAAO;AACvC,IAAiB,0BAA0B,OAAO;AAElD,UAAM,eAAe,QAAQ;AAE7B,aAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,UAAI,iBAAiB;AAGrB,yBAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,wBAAkB;AAIlB,MAAQ,0BAA0B,OAAO;AACzC,MAAiB,4BAA4B,OAAO;AAEpD,eAAS,aAAa,GAAG,aAAa,kBAAkB,EAAE,YAC1D;AAEI,2BAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,0BAAkB;AAAA,MACtB;AAIA,UAAI,UAAU;AACd,MAAQ,sBAAsB,SAAS,OAAO;AAC9C,MAAiB,wBAAwB,SAAS,OAAO;AAEzD,eAAS,aAAa,GAAG,aAAa,kBAAkB,EAAE,YAC1D;AAEI,2BAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,0BAAkB;AAAA,MACtB;AAKA,yBAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,wBAAkB;AAIlB,gBAAU;AACV,MAAQ,sBAAsB,SAAS,OAAO;AAC9C,MAAiB,wBAAwB,SAAS,OAAO;AAEzD,eAAS,aAAa,GAAG,aAAa,kBAAkB,EAAE,YAC1D;AAEI,2BAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,0BAAkB;AAAA,MACtB;AAAA,IAGJ;AAEA,kBAAc,IAAI,mBAAmB,mBAAmB,IAAI;AAE5D;AACI,MAAiB,2BAA2B,OAAO;AAEnD,UAAI,iBAAiB;AAErB,eAAS,aAAa,GAAG,aAAa,kBAAkB,EAAE,YAC1D;AAEI,2BAAmB,OAAO,cAAc,GAAG,OAAO;AAClD,0BAAkB;AAAA,MACtB;AACA,oBAAc;AAAA,IAClB;AAEA,IAAiB,wBAAwB,OAAO;AAGhD,YAAQ,OAAQ,OAAO,UAAU,EAAE,QAAQ,kBAAkB,qBAAsB;AACnF,uBAAmB,OAAO,UAAU,GAAG,OAAO;AAE9C,YAAQ,iBAAiB,OAAO;AAChC,YAAQ,OAAQ,aAAa,KAAK,QAAQ,UAAW;AAErD;AAAA,EACJ;AAEA,UAAQ,MAAM,gCAAgC,WAAW;AAC7D;AAEA,IAAM,aAAa,IAAI,QAAQ,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC;AAE1F,SAAS,0BAA0B,SAAS,SAAS,SAC5D;AAGI,QAAM,oBAAoB;AAC1B,QAAM,YAAY,kBAAkB;AACpC,QAAM,cAAc,kBAAkB;AAGtC,MAAI,YAAY,UAAU,IAC1B;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,kBAAkB;AAGhC,QAAM,QAAQ,MAAM,WAAW,OAAO;AAGtC,MAAI,MAAM,WAAW,UAAU,QAC/B;AACI,WAAO;AAAA,EACX;AAGA,MAAI,MAAM,aAAa,MACvB;AACI,WAAO;AAAA,EACX;AAGA,MAAI,aAAa,sBAAsB,UAAU,QAAQ,MAAM,MAAM;AAErE,MAAI,eAAe,OACnB;AACI,WAAO;AAAA,EACX;AAGA,QAAM,OAAO,MAAM,UAAU,MAAM,MAAM;AACzC,QAAM,UAAiB,aAAa,OAAO,IAAI;AAC/C,UAAQ,OAAO,KAAK,SAAS,WAAW,iBAAiB,YAAY,QAAQ;AAE7E,MAAI,QAAQ,UACZ;AACI,WAAO;AAAA,EACX;AAGA,QAAM,WAAW,MAAM,UAAU,YAAY,MAAM;AACnD,eAAoB,sBAAsB,OAAO,UAAU,IAAI;AAE/D,MAAI,eAAe,OACnB;AACI,WAAO;AAAA,EACX;AAEA,QAAM,kBAAkB,MAAM;AAE9B,MAAI,mBAAmB,MACvB;AACI,UAAM,MAAM,IAAI,UAAU,MAAM,KAAK,GAAG,MAAM,SAAS,MAAM,QAAQ;AACrE,UAAM,MAAM,IAAI,UAAU,UAAU,KAAK,GAAG,MAAM,SAAS,UAAU,QAAQ;AAC7E,iBAAa,gBAAgB,KAAK,KAAK,MAAM,mBAAmB;AAEhE,QAAI,eAAe,OACnB;AACI,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,MAAI,MAAM,SAAS,YAAY,sBAC/B;AACI,UAAM,YAAY,QAAQ;AAC1B,UAAMC,MAAK,iBAAiB,WAAW,MAAM,aAAa,QAAQ,MAAM;AACxE,UAAMC,MAAK,iBAAiB,WAAW,MAAM,aAAa,QAAQ,MAAM;AAGxE,UAAM,KAAKA,IAAG,IAAID,IAAG;AACrB,UAAM,KAAKC,IAAG,IAAID,IAAG;AACrB,UAAM,MAAM,kBAAkB;AAC9B,UAAM,MAAM,kBAAkB;AAC9B,UAAM,MAAM,kBAAkB;AAC9B,UAAM,MAAM,kBAAkB;AAG9B,QAAI,KAAK,MAAMA,IAAG;AAClB,QAAI,KAAK,MAAMA,IAAG;AAClB,UAAM,UAAU,KAAK,KAAK,KAAK;AAG/B,SAAK,MAAMA,IAAG;AACd,SAAK,MAAMA,IAAG;AACd,UAAM,UAAU,KAAK,KAAK,KAAK;AAE/B,QAAI,UAAU,KAAO,UAAU,GAC/B;AACI,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,QAAM,QAAQ,IAAI,WAAW;AAC7B,QAAM,SAAiB,yBAAyB,KAAK;AACrD,QAAM,SAAiB,yBAAyB,SAAS;AACzD,QAAM,SAAgB,YAAY,SAAS,UAAU;AACrD,QAAM,SAAS,kBAAkB;AACjC,QAAM,OAAO,kBAAkB;AAE/B,MAAI,cAAc,kBAAkB;AAEpC,MAAI,SAAS;AACb,MAAI,SAAS,eAAe,KAAK;AAEjC,MAAI,IAAM,OAAO,KAAK,OAAO,IAAI,kBAAkB,UACnD;AACI,kBAAc,OAAO;AACrB,aAAS;AAAA,EACb,WACS,MAAQ,OAAO,GACxB;AACI,UAAM,WAAmB,mBAAmB,SAAS;AACrD,UAAM,SAAS,YAAY,CAAE,QAAS,GAAG,GAAU,sBAAsB;AACzE,aAAS,eAAe,KAAK;AAE7B,QAAI,IAAM,OAAO,KAAK,OAAO,IAAI,kBAAkB,UACnD;AACI,oBAAc,OAAO;AACrB,eAAS;AAAA,IACb;AAAA,EACJ;AAEA,MAAI,WAAW,MAAM,wBAAwB,UAAU,uBACvD;AAEI,UAAM,aAAa,oBAAqB,MAAM,QAAQ,WAAY;AAClE,UAAM,aAAa,oBAAqB,MAAM,QAAQ,WAAY;AAClE,UAAM,WAAW,IAAI,WAAW;AAChC,sBAAmB,OAAO,YAAY,WAAW,YAAY,QAAS;AACtE,UAAM,WAAW,IAAI,UAAW,MAAM,KAAK,GAAG,MAAM,SAAS,MAAM,QAAS;AAC5E,UAAM,WAAW,IAAI,UAAW,UAAU,KAAK,GAAG,MAAM,SAAS,UAAU,QAAS;AAIpF,aAAS,MAAM,YAAa,UAAU,UAAU,UAAU,MAAM,eAAgB;AAAA,EACpF;AAEA,MAAI,QACJ;AACI,sBAAkB,WAAW;AAAA,EACjC;AAEA,SAAO;AACX;AAEA,IAAM,sBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ;AACb,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEA,IAAM,IAAI,IAAI,OAAO;AACrB,IAAM,KAAK,IAAI,OAAO;AACtB,IAAM,cAAc,IAAI,QAAQ,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC;AAG3F,SAAS,kBAAkB,OAAO,cACzC;AACI,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAC3D,UAAQ,OAAO,KAAK,gBAAgB,eAAe,SAAS,KAAK,KAAK;AACtE,QAAM,cAAc,SAAS,KAAK,KAAK,YAAY;AACnD,UAAQ,OAAO,YAAY,MAAM;AAEjC,QAAM,SAAS,MAAM;AAErB,QAAM,QAAe,YAAY,aAAa,WAAW;AAGzD,IAAE,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,YAAY;AACtF,IAAE,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,YAAY;AACtF,QAAME,OAAM,IAAI,YAAY,GAAG,MAAM,EAAE;AAGvC,KAAG,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,YAAY;AACvF,KAAG,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,YAAY;AACvF,QAAM,MAAM,IAAI,YAAY,IAAI,MAAM,EAAE;AAExC,QAAM,aAAa,MAAM,WAAW,MAAM,WAAW,aAAa;AAClE,QAAM,gBAAgB,MAAM,WAAW,MAAM,WAAW,gBAAgB;AACxE,QAAM,cAAc,MAAM,WAAW,MAAM,WAAW,cAAc;AACpE,QAAM,WAAW,MAAM,UAAU,YAAY,MAAM;AAEnD,QAAM,UAAU,IAAI,oBAAoB;AACxC,UAAQ,QAAQ;AAChB,UAAQ,QAAQ;AAChB,UAAQ,cAAc;AACtB,UAAQ,WAAW;AAEnB,QAAM,WAAW,YAAY;AAE7B,MAAI,UAAU,SAAS;AAEvB,SAAO,WAAW,eAClB;AAEI,UAAM,YAAY,OAAO,OAAO;AAChC,YAAQ,OAAO,UAAU,UAAU,IAAI;AAEvC,cAAU,UAAU;AAGpB,cAAU,SAAS;AAEnB,YAAQ,YAAY;AAGpB,wBAAoBA,MAAK,UAAU,eAAe,CAAC;AACnD,YAAQ,aAAa,EAAE;AACvB,YAAQ,aAAa,EAAE;AAGvB,wBAAoB,KAAK,UAAU,eAAe,CAAC;AACnD,YAAQ,aAAa,EAAE;AACvB,YAAQ,aAAa,EAAE;AAEvB,UAAM,OAAO,UAAU;AACvB,UAAM,OAAe,mBAAmB,WAAW,GAAG;AACtD,UAAM,MAAM,aAAa,MAAM,IAAI;AAGnC,cAAU,OAAO;AAGjB,QAAI,UAAU,UACd;AACI;AAAA,IACJ;AAEA,wBAAoB,YAAY,KAAK,sBAAsB,2BAA2B,OAAO;AAE7F,QAAI,UACJ;AACI,0BAAoB,eAAe,KAAK,sBAAsB,2BAA2B,OAAO;AAChG,0BAAoB,aAAa,KAAK,sBAAsB,2BAA2B,OAAO;AAAA,IAClG;AAAA,EACJ;AAEA,QAAM,sBAA6B;AACnC,QAAM,aAAoB;AAE1B,MAAI,QAAQ,WAAW,GACvB;AAEI,UAAMC,KAAI,QAAQ,MAAM,IAAI,MAAM,IAAI,QAAQ,QAAQ;AACtD,UAAMJ,KAAI,OAAO,MAAM,IAAI,MAAM,IAAI,QAAQ,QAAQ;AACrD,UAAM,SAAS,MAAMA,IAAG,eAAeI,IAAG,MAAM,WAAW,CAAC;AAG5D,UAAM,YAAY,IAAI,YAAY,QAAQA,EAAC;AAC3C,gBAAY,YAAY;AACxB,gBAAY,SAASJ;AACrB,gBAAY,YAAYI;AACxB,gBAAY,WAAWJ,GAAE;AACzB,gBAAY,WAAWA,GAAE;AAGzB,cAAU,SAAS;AAEnB,WAAO,WAAW,eAClB;AACI,YAAM,QAAQ,OAAO,OAAO;AAG5B,YAAM,OAAe,mBAAmB,OAAO,SAAS;AACxD,WAAK,eAAe;AACpB,WAAK,eAAe;AACpB,WAAK,eAAe;AACpB,WAAK,eAAe;AACpB,YAAM,OAAO;AAEb,UAAI,CAAC,gBAAgB,MAAM,SAAS,IAAI,GACxC;AACI,cAAM,UAAU,IAAI;AAAA,UAAO,KAAK,cAAc;AAAA,UAAY,KAAK,cAAc;AAAA,UACzE,KAAK,cAAc;AAAA,UAAY,KAAK,cAAc;AAAA,QAAU;AAChE,cAAM,UAAU;AAEhB,cAAM,eAAe;AACrB,oBAAY,cAAc;AAAA,MAC9B;AAEA,gBAAU,MAAM;AAAA,IACpB;AAAA,EACJ,OAEA;AAII,gBAAY,YAAY,YAAY,UAAU;AAC9C,gBAAY,WAAW,YAAY,OAAO;AAC1C,gBAAY,WAAW,YAAY,OAAO;AAG1C,cAAU,SAAS;AAEnB,WAAO,WAAW,eAClB;AACI,YAAM,QAAQ,OAAO,OAAO;AAI5B,UAAI,CAAC,gBAAgB,MAAM,SAAS,MAAM,IAAI,GAC9C;AACI,cAAM,UAAU,IAAI;AAAA,UAAO,MAAM,KAAK,cAAc;AAAA,UAAY,MAAM,KAAK,cAAc;AAAA,UACrF,MAAM,KAAK,cAAc;AAAA,UAAY,MAAM,KAAK,cAAc;AAAA,QAAU;AAC5E,cAAM,UAAU;AAEhB,cAAM,eAAe;AACrB,oBAAY,cAAc;AAAA,MAC9B;AAEA,gBAAU,MAAM;AAAA,IACpB;AAAA,EACJ;AACJ;AAEO,SAAS,eAAe,YAAY,UAAU,aACrD;AAGI,QAAM,cAAc;AAEpB,UAAQ,OAAO,cAAc,QAAQ;AAErC,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,WAAW,YAAY,WAAW,CAAC;AACzC,sBAAkB,YAAY,OAAO,QAAQ;AAAA,EACjD;AACJ;AAEO,SAAS,iBAAiB,YAAY,UAAU,aACvD;AAGI,QAAM,cAAc;AAEpB,UAAQ,OAAO,cAAc,QAAQ;AAErC,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,WAAW,YAAY,aAAa,CAAC;AAC3C,sBAAkB,YAAY,OAAO,QAAQ;AAAA,EACjD;AACJ;AAGO,SAAS,QAAQ,OAAO,aAC/B;AAGI,QAAM,aAAa;AAEnB,sBAAoB,KAAK;AAIzB,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAC3D,QAAM,iBAAiB,SAAS,KAAK;AAErC,MAAI,mBAAmB,GACvB;AAEI;AAAA,EACJ;AAGA,cAAY,gBAAgB;AAC5B,cAAY,aAAa,oBAAoB,MAAM,gBAAgB,gBAAgB,aAAa;AAChG,cAAY,kBAAkB;AAC9B,cAAY,eAAe,oBAAoB,MAAM,gBAAgB,gBAAgB,eAAe;AAGpG;AACI,UAAM,QAAQ,MAAM;AACpB,UAAM,SAAS,MAAM;AAErB,gBAAY,OAAO,SAAS,KAAK;AACjC,gBAAY,SAAS,SAAS,OAAO;AAIrC,QAAI,kBAAkB;AACtB,QAAI,mBAAmB;AAEvB,aAAS,IAAI,GAAG,IAAI,qBAAqB,GAAG,EAAE,GAC9C;AACI,YAAM,uBAAuB,OAAO,CAAC,EAAE,SAAS;AAChD,YAAM,qBAAqB,OAAO,CAAC,EAAE,OAAO;AAC5C,YAAM,iBAAiB,uBAAuB;AAC9C,0BAAoB,iBAAiB,IAAI,IAAI;AAG7C,yBAAmB;AAAA,IACvB;AAGA;AACI,YAAM,qBAAqB,MAAM;AAIjC,aAAO,mBAAmB,SAAS,gBACnC;AACI,2BAAmB,KAAK,IAAI,gBAAgB,CAAC;AAAA,MACjD;AAAA,IAGJ;AAEA,UAAM,cAAc,MAAM;AAC1B,UAAM,kBAAkB;AACxB,UAAM,gBAAgB,kBAAkB;AAKxC,QAAI,gBAAgB,KAAK;AACzB,QAAI;AAEJ,QAAI,iBAAiB,gBAAgB,eACrC;AAEI,sBAAgB,KAAK,MAAM,iBAAiB,aAAa;AACzD,uBAAiB;AAAA,IACrB,OAEA;AACI,uBAAiB,KAAK,MAAO,iBAAiB,KAAM,CAAC,IAAI;AAAA,IAC7D;AAKA,UAAM,qBAAqB,IAAI,MAAM,kBAAkB;AACvD,UAAM,yBAAyB,IAAI,MAAM,kBAAkB;AAC3D,UAAM,0BAA0B,IAAI,MAAM,kBAAkB;AAE5D,UAAM,mBAAmB,IAAI,MAAM,kBAAkB;AACrD,UAAM,uBAAuB,IAAI,MAAM,kBAAkB;AACzD,UAAM,wBAAwB,IAAI,MAAM,kBAAkB;AAE1D,UAAM,kBAAkB;AACxB,UAAM,mBAAmB;AAEzB,UAAM,uBAAuB,OAA0B,gBAAgB,EAAE,SAAS;AAClF,UAAM,6BAA6B;AAAA,MAC/B,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,MAAM;AAAE,eAAO,IAAqB,oBAAoB;AAAA,MAAG;AAAA,IAC/D;AAEA,UAAM,OAA0B,gBAAgB,EAAE,sBAAsB;AAGxE,QAAI,mBAAmB;AACvB,QAAI,oBAAoB,mBAAmB,IAAI,KAAK,MAAO,mBAAmB,KAAM,CAAC,IAAI,IAAI;AAE7F,QAAI,mBAAmB,mBAAmB,eAC1C;AAEI,yBAAmB,KAAK,MAAM,mBAAmB,aAAa;AAC9D,0BAAoB;AAAA,IACxB;AAGA,QAAI,iBAAiB;AACrB,QAAI,kBAAkB,kBAAkB,IAAI,KAAK,MAAO,kBAAkB,KAAM,CAAC,IAAI,IAAI;AAEzF,QAAI,kBAAkB,iBAAiB,eACvC;AAEI,uBAAiB,KAAK,MAAM,kBAAkB,aAAa;AAC3D,wBAAkB;AAAA,IACtB;AAEA,QAAI,aAAa;AAGjB,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAGd,kBAAc;AAEd,UAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,MAAM,IAAI,cAAc,CAAC;AAC3E,UAAM,aAAa,oBAAoB,MAAM,gBAAgB,gBAAgB,aAAa;AAC1F,UAAM,gBAAgB,oBAAoB,MAAM,gBAAgB,mBAAmB,gBAAgB;AACnG,UAAM,cAAc,oBAAoB,MAAM,gBAAgB,iBAAiB,cAAc;AAC7F,UAAM,cAAc,oBAAoB,MAAM,gBAAgB,iBAAiB,cAAc;AAM7F,QAAI,MAAM,iBAAiB,eAC3B;AACI,oBAAc,OAAO,MAAM,aAAa;AAAA,IAC5C;AAGA,aAAS,IAAI,GAAG,IAAI,gBAAgB,EAAE,GACtC;AACI,YAAM,QAAQ,IAAI,cAAc;AAChC,YAAM,aAAa,IAAI;AACvB,YAAM,QAAQ;AACd,YAAM,YAAY,kBAAkB;AACpC,YAAM,YAAY;AAClB,iBAAW,CAAC,IAAI;AAAA,IACpB;AACA,eAAW,iBAAiB,CAAC,EAAE,QAAQ,kBAAkB,iBAAiB,KAAK;AAG/E,aAAS,IAAI,GAAG,IAAI,iBAAiB,EAAE,GACvC;AACI,YAAM,QAAQ,IAAI,cAAc;AAChC,YAAM,aAAa,IAAI;AACvB,YAAM,QAAQ;AACd,YAAM,YAAY,kBAAkB;AACpC,YAAM,YAAY;AAClB,kBAAY,CAAC,IAAI;AAAA,IACrB;AAEA,QAAI,kBAAkB,GACtB;AACI,kBAAY,kBAAkB,CAAC,EAAE,QAAQ,mBAAmB,kBAAkB,KAAK;AAAA,IACvF;AAGA,aAAS,IAAI,GAAG,IAAI,mBAAmB,EAAE,GACzC;AACI,YAAM,QAAQ,IAAI,cAAc;AAChC,YAAM,aAAa,IAAI;AACvB,YAAM,QAAQ;AACd,YAAM,YAAY,kBAAkB;AACpC,YAAM,YAAY;AAClB,oBAAc,CAAC,IAAI;AAAA,IACvB;AAEA,QAAI,oBAAoB,GACxB;AACI,oBAAc,oBAAoB,CAAC,EAAE,QAAQ,oBAAoB,oBAAoB,KAAK;AAAA,IAC9F;AAGA,UAAM,mBAAmB,IAAI,MAAM,kBAAkB;AACrD,QAAI,iBAAiB;AAErB,aAAS,IAAI,GAAG,IAAI,kBAAkB,EAAE,GACxC;AACI,uBAAiB,CAAC,IAAI;AACtB,YAAM,uBAAuB,sBAAsB,CAAC;AACpD,YAAM,sBAAsB,qBAAqB,CAAC;AAElD,eAAS,IAAI,GAAG,IAAI,sBAAsB,EAAE,GAC5C;AACI,cAAM,QAAQ,IAAI,cAAc;AAChC,cAAM,aAAa,IAAI;AACvB,cAAM,QAAQ;AACd,cAAM,YAAY,kBAAkB;AACpC,cAAM,YAAY;AAClB,oBAAY,iBAAiB,CAAC,IAAI;AAAA,MACtC;AAEA,UAAI,uBAAuB,GAC3B;AACI,oBAAY,iBAAiB,uBAAuB,CAAC,EAAE,QACnD,iBAAiB,CAAC,KAAK,uBAAuB,KAAK;AACvD,0BAAkB;AAAA,MACtB;AACA,YAAM,yBAAyB,wBAAwB,CAAC;AACxD,YAAM,wBAAwB,uBAAuB,CAAC;AAEtD,eAAS,IAAI,GAAG,IAAI,wBAAwB,EAAE,GAC9C;AACI,cAAM,QAAQ,IAAI,cAAc;AAChC,cAAM,aAAa,IAAI;AACvB,cAAM,QAAQ;AACd,cAAM,YAAY,kBAAkB;AACpC,cAAM,YAAY;AAClB,oBAAY,iBAAiB,CAAC,IAAI;AAAA,MACtC;AAEA,UAAI,yBAAyB,GAC7B;AACI,oBAAY,iBAAiB,yBAAyB,CAAC,EAAE,QACrD,mBAAmB,CAAC,KAAK,yBAAyB,KAAK;AAC3D,0BAAkB;AAAA,MACtB;AAAA,IACJ;AACA,UAAM,YAAY;AAClB,YAAQ,OAAO,cAAc,iBAAiB,yBAAyB,SAAS,QAAQ,eAAe,EAAE;AAGzG,QAAI,KAAK;AAGT,UAAM,qBAAqB,CAAC,OAAO,MAAM,QAAQ,YAAY,aAAa,OAC1E;AACI,YAAM,OAAO;AACb,YAAM,SAAS;AACf,YAAM,aAAa;AACnB,YAAM,aAAa;AACnB,YAAM,kBAAkB;AAAA,IAC5B;AAGA,uBAAmB,OAAO,IAAI,GAAG,kBAAkB,uBAAuB,aAAa,eAAe;AAGtG,uBAAmB,OAAO,IAAI,GAAG,kBAAkB,yBAAyB,eAAe,iBAAiB;AAG5G,uBAAmB,OAAO,IAAI,GAAG,kBAAkB,6BAA6B,YAAY,cAAc;AA8B1G,uBAAmB,OAAO,IAAI,GAAG,kBAAkB,4BAA4B,YAAY,cAAc;AA8BzG,uBAAmB,OAAO,IAAI,GAAG,kBAAkB,uBAAuB,eAAe,iBAAiB;AAE1G,YAAQ,OAAO,OAAO,YAAY,sBAAsB;AAExD,YAAQ,OAAO,eAAe,aAAa;AAE3C,gBAAY,QAAQ;AACpB,gBAAY,SAAS;AACrB,gBAAY,WAAW;AACvB,gBAAY,yBAAyB;AACrC,gBAAY,mBAAmB;AAC/B,gBAAY,cAAc;AAC1B,gBAAY,aAAa;AACzB,gBAAY,SAAS;AAErB;AACI,YAAM,gBAAgB,IAAI,gBAAgB;AAC1C,oBAAc,UAAU;AACxB,oBAAc,cAAc;AAC5B,mBAAa,aAAa;AAAA,IAC9B;AAEA,UAAM,gBAAgB;AAGtB,UAAM,mBAAmB,SAAS,QAAQ;AAE1C,aAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,YAAM,cAAc,MAAM,iBAAiB,CAAC;AAC5C,kBAAY,oBAA6B,sBAAsB,YAAY,mBAAmB,cAAc;AAC5G,kBAAY,oBAA6B,sBAAsB,YAAY,mBAAmB,gBAAgB;AAC9G,kBAAY,gBAAgB;AAC5B,kBAAY,iBAAiB;AAAA,IACjC;AAIA,yBAAqB,GAAG,gBAAgB,GAAG,WAAW;AAEtD,oBAAgB,MAAM,gBAAgB,WAAW;AACjD,oBAAgB,MAAM,gBAAgB,WAAW;AACjD,oBAAgB,MAAM,gBAAgB,aAAa;AACnD,oBAAgB,MAAM,gBAAgB,UAAU;AAGhD,oBAAgB,MAAM,gBAAgB,0BAA0B;AAAA,EAIpE;AAIA;AACI,YAAQ,OAAO,MAAM,gBAAgB,WAAW,CAAC;AAEjD,UAAM,YAAY,MAAM;AACxB,UAAM,SAAS,MAAM,gBAAgB;AAErC,aAAS,IAAI,GAAG,IAAI,oBAAoB,EAAE,GAC1C;AACI,YAAM,QAAQ,OAAO,CAAC;AACtB,YAAM,eAAe,MAAM,SAAS;AACpC,YAAM,cAAc,MAAM,SAAS;AAEnC,eAAS,IAAI,GAAG,IAAI,cAAc,EAAE,GACpC;AACI,cAAM,aAAa,YAAY,CAAC;AAEhC,aAAK,WAAW,WAAW,kBAAkB,0BAA0B,GACvE;AACI;AAAA,QACJ;AAEA,cAAM,QAAQ,IAAI,kBAAkB;AACpC,cAAM,gBAAgB;AACtB,cAAM,WAAW,IAAI,UAAU,GAAG,GAAG,CAAC;AACtC,cAAM,WAAW,IAAI,UAAU,GAAG,GAAG,CAAC;AAEtC,YAAI,MAAM;AACV,cAAM,aAAa,WAAW,SAAS;AAEvC,iBAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,gBAAM,KAAK,WAAW,SAAS,OAAO,CAAC;AACvC,gBAAM,gBAAgB,CAAC,GAAG;AAG1B,cAAI,gBAAgB,MAAM,iBAAiB,GAAG,mBAAmB,GACjE;AACI,kBAAM,gBAAgB;AACtB,kBAAM,SAAS,GAAG;AAClB,kBAAM,SAAS,GAAG;AAClB,kBAAM;AAAA,UACV;AAAA,QACJ;AAEA,YAAI,QAAQ,MACZ;AACI,gBAAM,UAAU,WAAW,SAAS;AACpC,gBAAM,UAAU,WAAW,SAAS;AAIpC,gBAAM,SAAS,MAAM,WAAW,WAAW,QAAQ;AACnD,gBAAM,SAAS,MAAM,WAAW,WAAW,QAAQ;AAEnD,gBAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,MAAM,SAAS,OAAO,QAAQ;AAC5E,gBAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,MAAM,SAAS,OAAO,QAAQ;AAE5E,gBAAM,gBAAgB,KAAK,KAAK;AAAA,QACpC;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,QAAM,YAAY,MAAM,iBAAiB,CAAC,EAAE;AAE5C,WAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,IAAS,eAAe,WAAW,MAAM,iBAAiB,CAAC,EAAE,iBAAiB;AAAA,EAClF;AAKA;AACI,UAAM,aAAa,MAAM;AACzB,UAAM,SAAS,MAAM;AACrB,UAAM,YAAY,UAAU;AAC5B,UAAM,OAAO,UAAU;AAEvB,aAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,UAAI,OAAO,KAAK,CAAC;AAEjB,aAAO,SAAS,IAChB;AACI,cAAM,MAAM,QAAQ,IAAI;AACxB,cAAM,eAAe,KAAK,IAAI;AAG9B,gBAAQ,OAAO,eAAe,SAAS,KAAK,KAAK;AACjD,cAAM,UAAU,SAAS,KAAK,KAAK,YAAY;AAG/C,cAAM,OAAO,MAAM,UAAU,QAAQ,MAAM;AAE3C,YAAI,UAAU,KAAK;AAEnB,eAAO,YAAY,eACnB;AAEI,gBAAM,QAAQ,OAAO,OAAO;AAE5B,cAAI,MAAM,cACV;AACI,oBAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,sCAA0B,YAAY,MAAM,UAAU,MAAM,OAAO;AACnE,kBAAM,eAAe;AAAA,UACzB,WACS,MAAM,QACf;AAEI,yBAAa,YAAY,MAAM,QAAQ;AAAA,UAC3C;AAEA,oBAAU,MAAM;AAAA,QACpB;AAGA,eAAO,OAAQ,OAAO;AAAA,MAC1B;AAAA,IACJ;AAAA,EACJ;AAGA,MAAI,YAAY,gBAAgB,GAChC;AAEI,mBAAe,GAAG,YAAY,eAAe,WAAW;AAAA,EAC5D;AAIA;AACI,UAAM,aAAa,MAAM;AACzB,UAAM,cAAc,WAAW,MAAM,WAAW,cAAc;AAC9D,UAAM,SAAS,MAAM;AACrB,UAAM,SAAS,MAAM;AAErB,UAAM,aAAa,YAAY;AAC/B,UAAM,gBAAgB,YAAY;AAGlC,aAAS,IAAI,GAAG,IAAI,eAAe,EAAE,GACrC;AACI,cAAQ,OAAO,KAAK,WAAW,CAAC,KAAK,WAAW,CAAC,IAAI,SAAS,KAAK,KAAK;AACxE,YAAM,cAAc,SAAS,KAAK,KAAK,WAAW,CAAC,CAAC;AAEpD,UAAI,YAAY,gBAAgB,OAChC;AACI;AAAA,MACJ;AAGA,kBAAY,cAAc;AAG1B,YAAM,WAAW,OAAO,YAAY,MAAM;AAE1C,UAAI,UAAU,SAAS;AAEvB,aAAO,YAAY,eACnB;AACI,cAAM,QAAQ,OAAO,OAAO;AAE5B,YAAI,MAAM,iBAAiB,OAC3B;AACI,oBAAU,MAAM;AAEhB;AAAA,QACJ;AAGA,cAAM,eAAe;AAErB,cAAM,WAAW,MAAM;AACvB,cAAM,UAAU,YAAY,QAAQ;AACpC,gBAAQ,OAAO,cAAc,QAAQ,MAAM,WAAW,cAAc;AAKpE,mCAA2B,aAAa,SAAS,MAAM,OAAO;AAE9D,kBAAU,MAAM;AAAA,MACpB;AAAA,IACJ;AAAA,EACJ;AAGA,MAAI,YAAY,kBAAkB,GAClC;AAEI,qBAAiB,GAAG,YAAY,iBAAiB,WAAW;AAAA,EAChE;AAGA;AACI,UAAM,aAAa,MAAM;AACzB,UAAM,cAAc,WAAW,MAAM,WAAW,cAAc;AAC9D,UAAM,SAAS,MAAM;AACrB,UAAM,SAAS,MAAM;AAErB,UAAM,eAAe,YAAY;AACjC,UAAM,kBAAkB,YAAY;AAGpC,aAAS,IAAI,GAAG,IAAI,iBAAiB,EAAE,GACvC;AACI,cAAQ,OAAO,KAAK,aAAa,CAAC,KAAK,aAAa,CAAC,IAAI,SAAS,KAAK,KAAK;AAC5E,YAAM,gBAAgB,SAAS,KAAK,KAAK,aAAa,CAAC,CAAC;AAExD,UAAI,cAAc,gBAAgB,OAClC;AACI;AAAA,MACJ;AAGA,oBAAc,cAAc;AAG5B,YAAM,aAAa,OAAO,cAAc,MAAM;AAE9C,UAAI,UAAU,WAAW;AAEzB,aAAO,YAAY,eACnB;AACI,cAAM,QAAQ,OAAO,OAAO;AAE5B,YAAI,MAAM,iBAAiB,OAC3B;AACI,oBAAU,MAAM;AAEhB;AAAA,QACJ;AAGA,cAAM,eAAe;AAErB,cAAM,WAAW,MAAM;AACvB,cAAM,UAAU,YAAY,QAAQ;AACpC,gBAAQ,OAAO,cAAc,QAAQ,MAAM,WAAW,cAAc;AAKpE,mCAA2B,aAAa,SAAS,MAAM,OAAO;AAE9D,kBAAU,MAAM;AAAA,MACpB;AAAA,IACJ;AAAA,EACJ;AAEA,kBAAgB,MAAM,gBAAgB,YAAY,YAAY;AAC9D,cAAY,eAAe;AAC3B,cAAY,kBAAkB;AAE9B,kBAAgB,MAAM,gBAAgB,YAAY,UAAU;AAC5D,cAAY,aAAa;AACzB,cAAY,gBAAgB;AAI5B,MAAI,MAAM,gBAAgB,MAC1B;AAGI,YAAQ,OAAO,MAAM,kBAAkB,aAAa;AACpD,QAAI,kBAAkB;AAEtB,aAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,YAAM,cAAc,MAAM,iBAAiB,CAAC;AAE5C,UAAI,YAAY,kBAAkB,iBAAiB,YAAY,iBAAiB,iBAChF;AACI,cAAM,gBAAgB,YAAY;AAClC,0BAAkB,YAAY;AAAA,MAClC;AAAA,IACJ;AAEA,UAAM,oBAAoB,MAAM,iBAAiB,CAAC,EAAE;AAEpD,aAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,MAAS,eAAe,mBAAmB,MAAM,iBAAiB,CAAC,EAAE,iBAAiB;AAAA,IAC1F;AAGA,UAAM,UAAU,SAAS,QAAQ;AACjC,UAAM,QAAQ,SAAS,QAAQ;AAE/B,aAAS,cAAc,QAAQ,GAAG,eAAe,GAAG,eAAe,GACnE;AACI,UAAa,SAAS,mBAAmB,WAAW,MAAM,MAC1D;AAEI;AAAA,MACJ;AAEA,YAAM,SAAS,QAAQ,WAAW;AAClC,YAAM,WAAW,OAAO;AAIxB,uBAAiB,OAAO,QAAQ;AAAA,IACpC;AAEA,yBAAqB,KAAK;AAAA,EAC9B;AACJ;;;AChoDO,SAAS,0BAA0B,SAAS,QACnD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,aAAa,QAAQ,eAAe,OAAO;AAC1D,QAAM,UAAU;AAChB,QAAM,eAAe;AACrB,QAAM,eAAe;AACzB;AAWO,SAAS,0BAA0B,SAC1C;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,SAAO,MAAM;AACjB;AAaO,SAAS,4BAA4B,SAAS,aACrD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AACnB,QAAM,cAAc;AACxB;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAcO,SAAS,+BAA+B,SAAS,WAAW,WACnE;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,cAAY,aAAa,WAAW,eAAe,OAAO;AAC1D,cAAY,aAAa,WAAW,eAAe,OAAO;AAC1D,QAAM,YAAY,KAAK,IAAI,WAAW,SAAS;AAC/C,QAAM,YAAY,KAAK,IAAI,WAAW,SAAS;AAC/C,QAAM,UAAU;AAChB,QAAM,eAAe;AACrB,QAAM,eAAe;AACzB;AASO,SAAS,6BAA6B,SAC7C;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,SAAO,MAAM;AACjB;AASO,SAAS,6BAA6B,SAC7C;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,SAAO,MAAM;AACjB;AAYO,SAAS,iCAAiC,SACjD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AAEzE,QAAM,QAAQ,WAAW,QAAQ,MAAM;AAEvC,MAAI,MAAM,QACV;AACI,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,mBAAmB,OAAO,KAAK,OAAO;AACzD,QAAM,aAAa,mBAAmB,OAAO,KAAK,OAAO;AAEzD,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,IAAI,MAAM,IAAI,EAAE;AACtB,QAAM,SAAS,SAAS,CAAC;AAEzB,SAAO;AACX;AAcO,SAAS,6BAA6B,SAAS,cACtD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,OAAK,cAAc,eAAe;AACtC;AAaO,SAAS,gCAAgC,SAChD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AAEzE,SAAO,KAAK,cAAc;AAC9B;AAaO,SAAS,+BAA+B,SAAS,OACxD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,OAAK,cAAc,QAAQ;AAC/B;AAaO,SAAS,sCAAsC,SAAS,cAC/D;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,OAAK,cAAc,eAAe;AACtC;AASO,SAAS,yBAAyB,SACzC;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,SAAO,MAAM;AACjB;AASO,SAAS,gCAAgC,SAChD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AACzE,QAAM,QAAQ,KAAK;AAEnB,SAAO,MAAM;AACjB;AAYO,SAAS,4BAA4B,SAAS,aACrD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,MAAI,gBAAgB,MAAM,cAAc,aACxC;AACI,UAAM,cAAc,cAAc;AAClC,UAAM,cAAc,eAAe;AAAA,EACvC;AACJ;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAUO,SAAS,8BAA8B,SAAS,YACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,aAAa;AACrC;AASO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAYO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,OAAO,uBAAuB,SAAS,YAAY,gBAAgB;AAEzE,SAAO,MAAM,QAAQ,KAAK,cAAc;AAC5C;AAUO,SAAS,iCAAiC,SAAS,OAC1D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,gBAAgB;AACxC;AASO,SAAS,iCAAiC,SACjD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAEO,SAAS,wBAAwB,OAAO,MAC/C;AACI,QAAM,QAAQ,KAAK;AAEnB,QAAM,aAAa,mBAAmB,OAAO,KAAK,OAAO;AACzD,QAAM,aAAa,mBAAmB,OAAO,KAAK,OAAO;AAEzD,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,IAAI,MAAM,IAAI,EAAE;AACtB,QAAM,OAAO,YAAY,CAAC;AAC1B,QAAM,SAAS,MAAM,UAAU,MAAM,eAAe,MAAM,eAAe,MAAM,gBAAgB,MAAM;AAErG,SAAO,QAAQ,OAAO,IAAI;AAC9B;AAEO,SAAS,uBAAuB,MAAM,SAC7C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAErB,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AAEjB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AAExB,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAEhD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAEhD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AAEpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AAEb,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,MAAM,aAAa;AAC7E,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,MAAM,aAAa;AAE7E,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,cAAc,MAAM,SAAS,QAAQ,SAAS,MAAM;AAE1D,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AACjB,QAAM,aAAa,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,WAAW;AACzD,QAAM,OAAO,YAAY,UAAU;AAEnC,QAAM,MAAM,QAAQ,IAAI,IAAI;AAC5B,QAAM,MAAM,QAAQ,IAAI,IAAI;AAC5B,QAAM,IAAI,KAAK,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM;AAChD,QAAM,YAAY,IAAI,IAAM,IAAM,IAAI;AAEtC,QAAM,mBAAmB,WAAW,MAAM,OAAO,MAAM,cAAc,QAAQ,CAAC;AAE9E,MAAI,QAAQ,uBAAuB,OACnC;AACI,UAAM,UAAU;AAChB,UAAM,eAAe;AACrB,UAAM,eAAe;AACrB,UAAM,eAAe;AAAA,EACzB;AACJ;AAEO,SAAS,yBAAyB,MAAM,SAC/C;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,KAAK,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,IAAI,EAAE,CAAC;AACjF,QAAM,aAAa,MAAM,MAAM,aAAa,EAAE;AAC9C,QAAM,OAAO,YAAY,UAAU;AAEnC,QAAM,eAAe,MAAM,UAAU,MAAM,eAAe,MAAM,eAAe,MAAM;AACrF,QAAM,IAAI,QAAQ,cAAc,IAAI;AAEpC,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK,QAAQ,IAAI,CAAC;AAC5C,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK,QAAQ,IAAI,CAAC;AAChD;AAEO,SAAS,qBAAqB,MAAM,SAAS,SACpD;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAEhB,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,KAAK,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,IAAI,EAAE,CAAC;AACjF,QAAM,aAAa,MAAM,MAAM,aAAa,EAAE;AAE9C,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,OAAO,YAAY,UAAU;AAEnC,MAAI,MAAM,iBAAiB,MAAM,YAAY,MAAM,aAAa,MAAM,gBAAgB,QACtF;AACI,QAAI,MAAM,QAAQ,GAClB;AACI,YAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC;AAC3E,YAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,YAAM,IAAI,SAAS,MAAM;AACzB,YAAM,OAAO,MAAM,iBAAiB,WAAW;AAE/C,YAAM,IAAI,MAAM,iBAAiB,YAAY,MAAM;AACnD,YAAM,UAAU,CAAC,KAAK,OAAO,QAAQ,MAAM,iBAAiB,eAAe,MAAM;AACjF,YAAM,WAAW;AAEjB,YAAM,IAAI,QAAQ,SAAS,IAAI;AAC/B,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC5B;AAEA,QAAI,MAAM,aACV;AACI;AACI,cAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC;AAC3E,cAAM,OAAO,MAAM,MAAM,EAAE;AAE3B,cAAM,IAAI,SAAS,MAAM;AAEzB,YAAI,OAAO;AACX,YAAI,YAAY;AAChB,YAAI,eAAe;AAEnB,YAAI,IAAI,GACR;AACI,iBAAO,IAAI,QAAQ;AAAA,QACvB,WACS,SACT;AACI,iBAAO,QAAQ,cAAc,WAAW;AACxC,sBAAY,QAAQ,cAAc;AAClC,yBAAe,QAAQ,cAAc;AAAA,QACzC;AAEA,cAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,cAAM,aAAa,KAAK,IAAI,GAAK,MAAM,eAAe,OAAO;AAC7D,cAAM,eAAe,aAAa,MAAM;AACxC,cAAM,eAAe;AAErB,cAAM,IAAI,QAAQ,cAAc,IAAI;AACpC,aAAK,SAAS,IAAI,IAAI,CAAC;AACvB,cAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,aAAK,SAAS,IAAI,IAAI,CAAC;AACvB,cAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MAC5B;AAEA;AACI,cAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC;AAC3E,cAAM,OAAO,MAAM,MAAM,EAAE;AAE3B,cAAM,IAAI,MAAM,YAAY;AAE5B,YAAI,OAAO;AACX,YAAI,YAAY;AAChB,YAAI,eAAe;AAEnB,YAAI,IAAI,GACR;AACI,iBAAO,IAAI,QAAQ;AAAA,QACvB,WACS,SACT;AACI,iBAAO,QAAQ,cAAc,WAAW;AACxC,sBAAY,QAAQ,cAAc;AAClC,yBAAe,QAAQ,cAAc;AAAA,QACzC;AAEA,cAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,cAAM,aAAa,KAAK,IAAI,GAAK,MAAM,eAAe,OAAO;AAC7D,cAAM,eAAe,aAAa,MAAM;AACxC,cAAM,eAAe;AAErB,cAAM,IAAI,QAAQ,CAAC,cAAc,IAAI;AACrC,aAAK,SAAS,IAAI,IAAI,CAAC;AACvB,cAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,aAAK,SAAS,IAAI,IAAI,CAAC;AACvB,cAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MAC5B;AAAA,IACJ;AAEA,QAAI,MAAM,aACV;AACI,YAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC;AAC3E,YAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,YAAM,UAAU,MAAM,aAAa,MAAM,aAAa;AACtD,YAAM,aAAa,MAAM;AACzB,YAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,YAAM,eAAe,aAAa,MAAM,eAAe,SAAS,CAAC,YAAY,UAAU;AACvF,YAAM,eAAe,MAAM,eAAe;AAE1C,YAAM,IAAI,QAAQ,cAAc,IAAI;AACpC,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC5B;AAAA,EACJ,OAEA;AACI,UAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC;AAC3E,UAAM,OAAO,MAAM,MAAM,EAAE;AAE3B,UAAM,IAAI,SAAS,MAAM;AAEzB,QAAI,OAAO;AACX,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,SACJ;AACI,aAAO,QAAQ,cAAc,WAAW;AACxC,kBAAY,QAAQ,cAAc;AAClC,qBAAe,QAAQ,cAAc;AAAA,IACzC;AAEA,UAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,UAAM,WAAW;AAEjB,UAAM,IAAI,QAAQ,SAAS,IAAI;AAC/B,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,EAC5B;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AACzB,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;AAEO,SAAS,oBAAoB,MAAM,MAAM,YAAY,YAC5D;AACI,QAAM,QAAQ,KAAK;AAEnB,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAE/D,QAAM,OAAO,YAAY,MAAM,IAAI,EAAE,CAAC;AAEtC,MAAI,MAAM,YAAY,MAAM,aAAa,MAAM,aAC/C;AACI,UAAM,OAAO,SAAS,IAAI,MAAM,WAAW,IAAI;AAC/C,UAAM,OAAO,SAAS,IAAI,MAAM,WAAW,IAAI;AAC/C,UAAM,SAAS,QAAQ,OAAOK,yBAAwB,YAAY,IAAI,CAAC;AAEvE,QAAI,MAAM,YAAY,eACtB;AACI,WAAK,YAAY,MAAM,MAAM,MAAM,GAAG,MAAM,MAAM,MAAM,GAAG,WAAW,oBAAoB,KAAK,OAAO;AAAA,IAC1G;AAEA,QAAI,MAAM,YAAY,SACtB;AACI,WAAK,YAAY,MAAM,MAAM,MAAM,GAAG,MAAM,MAAM,MAAM,GAAG,WAAW,aAAa,KAAK,OAAO;AAAA,IACnG;AAEA,QAAI,MAAM,YAAY,iBAAiB,MAAM,YAAY,SACzD;AACI,WAAK,YAAY,MAAM,MAAM,WAAW,cAAc,KAAK,OAAO;AAAA,IACtE;AAAA,EACJ;AAEA,OAAK,YAAY,IAAI,IAAI,WAAW,eAAe,KAAK,OAAO;AAC/D,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,WAAW,eAAe,KAAK,OAAO;AACtE,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,WAAW,eAAe,KAAK,OAAO;AAEtE,MAAI,MAAM,QAAQ,KAAO,MAAM,cAC/B;AACI,UAAM,QAAQ,SAAS,IAAI,MAAM,QAAQ,IAAI;AAC7C,SAAK,UAAU,MAAM,GAAG,MAAM,GAAG,GAAK,WAAW,cAAc,KAAK,OAAO;AAAA,EAC/E;AACJ;;;AC1pBO,SAAS,8BAA8B,SAAS,cACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,MAAI,iBAAiB,MAAM,eAAe,cAC1C;AACI,UAAM,eAAe,eAAe;AACpC,UAAM,eAAe,gBAAgB;AAAA,EACzC;AACJ;AASO,SAAS,iCAAiC,SACjD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAYO,SAAS,gCAAgC,SAAS,OACzD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAC3E,QAAM,eAAe,QAAQ;AACjC;AASO,SAAS,gCAAgC,SAChD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAYO,SAAS,uCAAuC,SAAS,cAChE;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAC3E,QAAM,eAAe,eAAe;AACxC;AASO,SAAS,uCAAuC,SACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAYO,SAAS,6BAA6B,SAAS,aACtD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,MAAI,gBAAgB,MAAM,eAAe,aACzC;AACI,UAAM,eAAe,cAAc;AACnC,UAAM,eAAe,eAAe;AACpC,UAAM,eAAe,eAAe;AAAA,EACxC;AACJ;AASO,SAAS,gCAAgC,SAChD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAeO,SAAS,2BAA2B,SAAS,OAAO,OAC3D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,MAAI,UAAU,MAAM,eAAe,oBAAoB,UAAU,MAAM,eAAe,kBACtF;AACI,UAAM,eAAe,mBAAmB,KAAK,IAAI,OAAO,KAAK;AAC7D,UAAM,eAAe,mBAAmB,KAAK,IAAI,OAAO,KAAK;AAC7D,UAAM,eAAe,eAAe;AACpC,UAAM,eAAe,eAAe;AAAA,EACxC;AACJ;AAYO,SAAS,6BAA6B,SAAS,aACtD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,MAAI,gBAAgB,MAAM,eAAe,aACzC;AACI,UAAM,eAAe,cAAc;AACnC,UAAM,eAAe,eAAe;AAAA,EACxC;AACJ;AASO,SAAS,gCAAgC,SAChD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAUO,SAAS,+BAA+B,SAAS,YACxD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAC3E,QAAM,eAAe,aAAa;AACtC;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAWO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,OAAO,uBAAuB,SAAS,YAAY,iBAAiB;AAE1E,SAAO,MAAM,QAAQ,KAAK,eAAe;AAC7C;AAUO,SAAS,kCAAkC,SAAS,OAC3D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAC3E,QAAM,eAAe,gBAAgB;AACzC;AASO,SAAS,kCAAkC,SAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,iBAAiB;AAE3E,SAAO,MAAM,eAAe;AAChC;AAEO,SAAS,yBAAyB,OAAO,MAChD;AACI,QAAM,MAAM,KAAK;AACjB,QAAM,aAAa,mBAAmB,OAAO,GAAG;AAEhD,QAAM,QAAQ,KAAK;AAEnB,QAAM,QAAQ,eAAe,WAAW,GAAG,MAAM,UAAU;AAC3D,QAAM,QAAQ,WAAW,KAAK;AAE9B,QAAM,QAAQ,MAAM;AACpB,QAAM,YAAY,QAAQ,MAAM,QAAQ;AACxC,QAAM,aAAa,SAAS,MAAM,eAAe,MAAM,eAAe,MAAM;AAE5E,QAAM,QAAQ,MAAM,QAAQ,WAAW,KAAK,GAAG,QAAQ,YAAY,KAAK,CAAC;AAEzE,SAAO;AACX;AAEO,SAAS,0BAA0B,OAAO,MACjD;AACI,SAAO,MAAM,QAAQ,KAAK,eAAe,QAAQ;AACrD;AA+CO,SAAS,wBAAwB,MAAM,SAC9C;AAEI,UAAQ,OAAO,KAAK,QAAQ,YAAY,iBAAiB;AAGzD,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AAEjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAMrB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AAGxB,UAAQ,OAAO,MAAM,YAAY,UAAU,eAAe,MAAM,YAAY,UAAU,WAAW;AAKjG,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAEhD,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,MAAM;AAG1B,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AACjE,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AAEjE,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAEhD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AAEpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AAEb,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AACvE,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AAEvE,QAAM,KAAK,SAAS,UAAU;AAC9B,QAAM,KAAK,SAAS,UAAU;AAE9B,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,QAAQ,eAAe,IAAI,MAAM,UAAU;AACjD,QAAM,cAAc,MAAM,SAAS,QAAQ,SAAS,MAAM;AAC1D,QAAM,aAAa,gBAAgB,IAAI,EAAE,IAAI,MAAM;AAEnD,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AAEjB,QAAM,IAAI,MAAM,MAAM,aAAa,MAAM,IAAI,EAAE,CAAC;AAChD,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,MAAM,KAAK;AAC5C,QAAM,KAAK,QAAQ,IAAI,MAAM,KAAK;AAGlC,QAAM,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC7C,QAAM,YAAY,IAAI,IAAM,IAAM,IAAI;AAEtC,QAAM,iBAAiB,WAAW,MAAM,OAAO,MAAM,cAAc,QAAQ,CAAC;AAE5E,MAAI,QAAQ,sBAAsB,OAClC;AACI,UAAM,UAAU,IAAI,OAAO,GAAG,CAAC;AAC/B,UAAM,gBAAgB;AACtB,UAAM,eAAe;AACrB,UAAM,eAAe;AACrB,UAAM,eAAe;AAAA,EACzB;AACJ;AAEO,SAAS,0BAA0B,MAAM,SAChD;AAEI,UAAQ,OAAO,KAAK,QAAQ,YAAY,iBAAiB;AAEzD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACvF,QAAM,SAAS,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAEvF,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,IAAI,MAAM,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,WAAW,GAAG,MAAM,IAAI,EAAE,CAAC;AAC1G,QAAM,QAAQ,eAAe,OAAO,eAAe,MAAM,KAAK;AAG9D,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAC5B,QAAM,eAAe,MAAM,gBAAgB,MAAM,eAAe,MAAM,eAAe,MAAM;AAG3F,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAC5B,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,eAAe,MAAM,QAAQ;AAEnC,QAAM,IAAI,MAAM,QAAQ,cAAc,KAAK,GAAG,QAAQ,aAAa,KAAK,CAAC;AACzE,QAAM,KAAK,eAAe,KAAK,cAAc,KAAK;AAClD,QAAM,KAAK,eAAe,KAAK,cAAc,KAAK;AAElD,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK;AAC/B,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK;AACnC;AAEO,SAAS,sBAAsB,MAAM,SAAS,SACrD;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,iBAAiB;AAEzD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAGhB,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,IAAI,MAAM,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,WAAW,GAAG,MAAM,IAAI,EAAE,CAAC;AAC1G,QAAM,QAAQ,eAAe,OAAO,eAAe,MAAM,KAAK;AAC9D,QAAM,cAAc,MAAM,OAAO,CAAC;AAGlC,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAG5B,MAAI,MAAM,cACV;AACI,UAAM,IAAI;AACV,UAAM,OAAO,MAAM,eAAe,WAAW;AAC7C,UAAM,YAAY,MAAM,eAAe;AACvC,UAAM,eAAe,MAAM,eAAe;AAE1C,UAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,UAAM,iBAAiB;AAEvB,UAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,UAAU;AAErB,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AACX,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AAAA,EACf;AAGA,MAAI,MAAM,aACV;AACI,UAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,QAAI,UAAU,MAAM,aAAa,MAAM,aAAa;AACpD,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,UAAM,eAAe,aAAa,MAAM,eAAe,SAAS,CAAC,YAAY,UAAU;AACvF,cAAU,MAAM,eAAe;AAE/B,UAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,UAAU;AAErB,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AACX,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AAAA,EACf;AAEA,MAAI,MAAM,aACV;AAEI;AACI,YAAM,IAAI,cAAc,MAAM;AAC9B,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAEA,YAAM,aAAa,MAAM;AACzB,YAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAI,UAAU,CAAC,MAAM,YAAY,aAAa,OAAO,QAAQ,eAAe;AAC5E,YAAM,eAAe,KAAK,IAAI,aAAa,SAAS,CAAG;AACvD,gBAAU,MAAM,eAAe;AAE/B,YAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAErB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AACX,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AAAA,IACf;AAGA;AACI,YAAM,IAAI,MAAM,mBAAmB;AACnC,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAEA,YAAM,aAAa,MAAM;AACzB,YAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAI,UAAU,CAAC,MAAM,YAAY,aAAa,OAAO,QAAQ,eAAe;AAC5E,YAAM,eAAe,KAAK,IAAI,aAAa,SAAS,CAAG;AACvD,gBAAU,MAAM,eAAe;AAE/B,YAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAErB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AACX,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AAAA,IACf;AAAA,EACJ;AAGA;AACI,UAAM,QAAQ,WAAW,KAAK;AAG9B,UAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,UAAM,KAAK,QAAQ,IAAI,KAAK;AAE5B,UAAM,OAAO,IAAI,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AAEhF,QAAI,OAAO,IAAI,OAAO;AACtB,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,SACJ;AACI,YAAM,IAAI,IAAI,OAAO,MAAM,OAAO,CAAC,GAAG,gBAAgB,OAAO,eAAe,OAAO,aAAa,IAAI,MAAM,UAAU;AACpH,aAAO,QAAQ,QAAQ,cAAc,UAAU,CAAC;AAChD,kBAAY,QAAQ,cAAc;AAClC,qBAAe,QAAQ,cAAc;AAAA,IACzC;AAEA,UAAM,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC/C,UAAM,MAAM,KAAK,KAAK,KAAK;AAC3B,QAAI,MAAM,KAAK;AAEf,QAAI,QAAQ,GACZ;AAEI,YAAM;AAAA,IACV;AAEA,UAAM,IAAI,IAAI,QAAQ,IAAI,OAAO,KAAK,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,CAAC;AAEhE,UAAM,IAAI,UAAU,GAAG,MAAM,MAAM,IAAI,CAAC;AACxC,UAAM,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,QAAQ,CAAC;AAC/H,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,QAAQ,KAAK,QAAQ;AAE3B,UAAM,IAAI,QAAQ,QAAQ,GAAG,KAAK;AAClC,UAAM,KAAK,QAAQ,IAAI,KAAK,QAAQ;AACpC,UAAM,KAAK,QAAQ,IAAI,KAAK,QAAQ;AAEpC,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AACX,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AAAA,EACf;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AACzB,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;AAEO,SAAS,qBAAqB,MAAM,MAAM,YAAY,YAC7D;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,iBAAiB;AACzD,QAAM,QAAQ,KAAK;AACnB,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,OAAO,eAAe,WAAW,GAAG,MAAM,UAAU;AAC1D,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AAEtB,OAAK,YAAY,IAAI,IAAI,IAAI,KAAK,OAAO;AAEzC,MAAI,MAAM,aACV;AACI,UAAM,QAAQ,SAAS,IAAI,MAAM,kBAAkB,IAAI;AACvD,UAAM,QAAQ,SAAS,IAAI,MAAM,kBAAkB,IAAI;AACvD,UAAM,OAAO,WAAW,IAAI;AAC5B,SAAK,YAAY,OAAO,OAAO,IAAI,KAAK,OAAO;AAC/C,SAAK,YAAY,SAAS,OAAO,KAAK,IAAI,GAAG,SAAS,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AACzF,SAAK,YAAY,SAAS,OAAO,KAAK,IAAI,GAAG,SAAS,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AAAA,EAC7F,OAEA;AACI,SAAK,YAAY,SAAS,IAAI,GAAK,IAAI,GAAG,SAAS,IAAI,GAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AAAA,EACvF;AAEA,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,IAAI,KAAK,OAAO;AAChD,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,IAAI,KAAK,OAAO;AACpD;;;AC/sBO,SAAS,6BAA6B,SAAS,cACtD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,MAAI,iBAAiB,MAAM,cAAc,cACzC;AACI,UAAM,cAAc,eAAe;AACnC,UAAM,cAAc,gBAAgB;AAAA,EACxC;AACJ;AASO,SAAS,gCAAgC,SAChD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAaO,SAAS,+BAA+B,SAAS,OACxD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,QAAQ;AAChC;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAUO,SAAS,sCAAsC,SAAS,cAC/D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,eAAe;AACvC;AASO,SAAS,sCAAsC,SACtD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAaO,SAAS,yBAAyB,SACzC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,WAAW,uBAAuB,SAAS,YAAY,gBAAgB;AAC7E,QAAM,aAAa,mBAAmB,OAAO,SAAS,OAAO;AAC7D,QAAM,aAAa,mBAAmB,OAAO,SAAS,OAAO;AAE7D,MAAI,QAAQ,gBAAgB,WAAW,GAAG,WAAW,CAAC,IAAI,SAAS,cAAc;AACjF,UAAQ,cAAc,KAAK;AAE3B,SAAO;AACX;AAaO,SAAS,4BAA4B,SAAS,aACrD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,MAAI,gBAAgB,MAAM,cAAc,aACxC;AACI,UAAM,cAAc,cAAc;AAClC,UAAM,cAAc,eAAe;AACnC,UAAM,cAAc,eAAe;AAAA,EACvC;AACJ;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AASO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AASO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAcO,SAAS,0BAA0B,SAAS,OAAO,OAC1D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,MAAI,UAAU,MAAM,cAAc,cAAc,UAAU,MAAM,cAAc,YAC9E;AACI,UAAM,cAAc,aAAa,KAAK,IAAI,OAAO,KAAK;AACtD,UAAM,cAAc,aAAa,KAAK,IAAI,OAAO,KAAK;AACtD,UAAM,cAAc,eAAe;AACnC,UAAM,cAAc,eAAe;AAAA,EACvC;AACJ;AAYO,SAAS,4BAA4B,SAAS,aACrD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,MAAI,gBAAgB,MAAM,cAAc,aACxC;AACI,UAAM,cAAc,cAAc;AAClC,UAAM,cAAc,eAAe;AAAA,EACvC;AACJ;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAaO,SAAS,8BAA8B,SAAS,YACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,aAAa;AACrC;AASO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAYO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,QAAQ,MAAM,cAAc;AAC7C;AAUO,SAAS,kCAAkC,SAAS,QAC3D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAC1E,QAAM,cAAc,iBAAiB;AACzC;AASO,SAAS,kCAAkC,SAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,gBAAgB;AAE1E,SAAO,MAAM,cAAc;AAC/B;AAEO,SAAS,wBAAwB,OAAO,MAC/C;AACI,QAAM,QAAQ,QAAQ,MAAM,OAAO,KAAK,cAAc,aAAa;AAEnE,SAAO;AACX;AAEO,SAAS,yBAAyB,OAAO,MAChD;AACI,QAAM,WAAW,KAAK;AACtB,QAAM,SAAS,MAAM,SAAS,SAAS,eAAe,SAAS,eAAe,SAAS;AAEvF,SAAO;AACX;AAgCO,SAAS,uBAAuB,MAAM,SAC7C;AAEI,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AACjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AACrB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AACxB,UAAQ,OAAQ,MAAM,YAAY,UAAU,eAAe,MAAM,YAAY,UAAU,aAAa,oBAAoB,MAAM,QAAQ,sBAAsB,MAAM,QAAQ,EAAG;AAE7K,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,MAAM;AAE1B,UAAQ,OAAQ,KAAK,eAAe,eAAe,KAAK,KAAK,KAAM;AACnE,UAAQ,OAAQ,KAAK,eAAe,eAAe,KAAK,KAAK,KAAM;AAEnE,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AACb,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,cAAc;AACxE,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,cAAc;AAGxE,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,cAAc,MAAM,SAAS,QAAQ,SAAS,MAAM;AAC1D,QAAM,aAAa,gBAAgB,SAAS,UAAU,GAAG,SAAS,UAAU,CAAC,IAAI,MAAM;AACvF,QAAM,aAAa,cAAc,MAAM,UAAU;AAEjD,QAAM,IAAI,KAAK;AACf,QAAM,YAAY,IAAI,IAAM,IAAM,IAAI;AACtC,QAAM,iBAAiB,WAAW,MAAM,OAAO,MAAM,cAAc,QAAQ,CAAC;AAE5E,MAAI,QAAQ,uBAAuB,OACnC;AACI,UAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACrC,UAAM,gBAAgB;AACtB,UAAM,eAAe;AACrB,UAAM,eAAe;AACrB,UAAM,eAAe;AAAA,EACzB;AACJ;AAEO,SAAS,yBAAyB,MAAM,SAC/C;AACI,UAAQ,OAAQ,KAAK,QAAQ,YAAY,gBAAiB;AAE1D,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,eAAe,MAAM,gBAAgB,MAAM,eAAe,MAAM,eAAe,MAAM;AAE3F,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,MAAM,aAAa;AAC/E,SAAO,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI;AAEnE,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,MAAM,aAAa;AAC/E,SAAO,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI;AACvE;AAEO,SAAS,qBAAqB,MAAM,SAAS,SACpD;AACI,UAAQ,OAAQ,KAAK,QAAQ,YAAY,gBAAiB;AAE1D,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,MAAI,KAAK,OAAO,eAAe,MAAM;AACrC,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO,eAAe,MAAM;AACrC,MAAI,KAAK,OAAO;AAEhB,QAAM,gBAAiB,KAAK,OAAO;AAKnC,MAAI,MAAM,gBAAgB,kBAAkB,OAC5C;AACI,UAAM,IAAI,gBAAgB,OAAO,eAAe,OAAO,aAAa,IAAI,MAAM;AAC9E,UAAM,OAAO,MAAM,eAAe,WAAW;AAC7C,UAAM,YAAY,MAAM,eAAe;AACvC,UAAM,eAAe,MAAM,eAAe;AAE1C,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,UAAM,iBAAiB;AAEvB,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AAGA,MAAI,MAAM,eAAe,kBAAkB,OAC3C;AACI,UAAM,OAAO,KAAK,KAAK,MAAM;AAC7B,QAAI,UAAU,CAAC,MAAM,YAAY;AACjC,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,UAAM,eAAe,aAAa,MAAM,eAAe,SAAS,CAAC,YAAY,UAAU;AACvF,cAAU,MAAM,eAAe;AAE/B,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AAEA,MAAI,MAAM,eAAe,kBAAkB,OAC3C;AACI,QAAI,aAAa,gBAAgB,OAAO,eAAe,OAAO,aAAa,IAAI,MAAM;AACrF,iBAAa,cAAc,UAAU;AAGrC;AACI,YAAM,IAAI,aAAa,MAAM;AAC7B,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAEA,YAAM,OAAO,KAAK;AAClB,UAAI,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AAClF,YAAM,aAAa,MAAM;AACzB,YAAM,eAAe,KAAK,IAAI,MAAM,eAAe,SAAS,CAAG;AAC/D,gBAAU,MAAM,eAAe;AAE/B,YAAM,KAAK;AACX,YAAM,KAAK;AAAA,IACf;AAKA;AACI,YAAM,IAAI,MAAM,aAAa;AAC7B,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAGA,YAAM,OAAO,KAAK;AAClB,UAAI,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AAClF,YAAM,aAAa,MAAM;AACzB,YAAM,eAAe,KAAK,IAAI,MAAM,eAAe,SAAS,CAAG;AAC/D,gBAAU,MAAM,eAAe;AAG/B,YAAM,KAAK;AACX,YAAM,KAAK;AAAA,IACf;AAAA,EACJ;AAGA;AAEI,UAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,UAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,UAAM,OAAO,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,GAAG,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,CAAC;AAE7E,QAAI,OAAO,IAAI,OAAO,GAAG,CAAC;AAC1B,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,SACJ;AACI,YAAM,MAAM,OAAO;AACnB,YAAM,MAAM,OAAO;AAEnB,YAAM,aAAa,MAAM,MAAM,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC,GAAG,MAAM,WAAW;AACjF,aAAO,QAAQ,QAAQ,cAAc,UAAU,UAAU;AACzD,kBAAY,QAAQ,cAAc;AAClC,qBAAe,QAAQ,cAAc;AAAA,IACzC;AAEA,UAAM,IAAI;AAAA,MACN,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,MACnB,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,IACvB;AACA,MAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,MAAE,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AAC3C,MAAE,GAAG,IAAI,EAAE,GAAG;AACd,MAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,UAAM,IAAI,UAAU,GAAG,MAAM,MAAM,IAAI,CAAC;AAExC,UAAM,UAAU,IAAI;AAAA,MAChB,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,MACtD,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,IAC1D;AACA,UAAM,cAAc,KAAK,QAAQ;AACjC,UAAM,cAAc,KAAK,QAAQ;AAEjC,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAC9B,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAAA,EAClC;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AACzB,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;AA2BO,SAAS,oBAAoB,MAAM,MAAM,YAAY,YAAY,UACxE;AAEI,UAAQ,OAAQ,KAAK,QAAQ,YAAY,gBAAiB;AAE1D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAE/D,QAAM,KAAK,WAAW;AAKtB,QAAM,IAAI;AACV,OAAK,WAAW,IAAI,GAAG,IAAI,KAAK,OAAO;AAEvC,QAAM,QAAQ,gBAAgB,WAAW,GAAG,WAAW,CAAC;AAExD,QAAM,IAAI,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,CAAC;AAC7D,QAAM,KAAK,MAAM,IAAI,CAAC;AACtB,OAAK,YAAY,IAAI,IAAI,IAAI,KAAK,OAAO;AAsBzC,QAAM,QAAQ,WAAW;AACzB,OAAK,YAAY,WAAW,GAAG,IAAI,OAAO,KAAK,OAAO;AACtD,OAAK,YAAY,IAAI,IAAI,OAAO,KAAK,OAAO;AAC5C,OAAK,YAAY,WAAW,GAAG,IAAI,OAAO,KAAK,OAAO;AAC1D;;;AC1rBO,SAAS,0BAA0B,SAAS,cACnD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,MAAI,iBAAiB,MAAM,WAAW,cACtC;AACI,UAAM,WAAW,eAAe;AAChC,UAAM,WAAW,gBAAgB;AAAA,EACrC;AACJ;AASO,SAAS,6BAA6B,SAC7C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAaO,SAAS,4BAA4B,SAAS,OACrD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,QAAQ;AAC7B;AASO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAUO,SAAS,mCAAmC,SAAS,cAC5D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,eAAe;AACpC;AASO,SAAS,mCAAmC,SACnD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAcO,SAAS,yBAAyB,SAAS,aAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,MAAI,MAAM,WAAW,gBAAgB,aACrC;AACI,UAAM,WAAW,eAAe;AAChC,UAAM,WAAW,eAAe;AAChC,UAAM,WAAW,cAAc;AAAA,EACnC;AACJ;AASO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AASO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AASO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAeO,SAAS,uBAAuB,SAAS,OAAO,OACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,MAAI,UAAU,MAAM,WAAW,oBAAoB,UAAU,MAAM,WAAW,kBAC9E;AACI,UAAM,WAAW,mBAAmB,KAAK,IAAI,OAAO,KAAK;AACzD,UAAM,WAAW,mBAAmB,KAAK,IAAI,OAAO,KAAK;AACzD,UAAM,WAAW,eAAe;AAChC,UAAM,WAAW,eAAe;AAAA,EACpC;AACJ;AAYO,SAAS,yBAAyB,SAAS,aAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,MAAI,MAAM,WAAW,gBAAgB,aACrC;AACI,UAAM,WAAW,eAAe;AAChC,UAAM,WAAW,cAAc;AAAA,EACnC;AACJ;AASO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAUO,SAAS,2BAA2B,SAAS,YACpD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,aAAa;AAClC;AASO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAYO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,QAAQ,MAAM,WAAW;AAC1C;AAaO,SAAS,+BAA+B,SAAS,QACxD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,iBAAiB;AACtC;AASO,SAAS,+BAA+B,SAC/C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,qBAAqB,OAAO,MAC5C;AACI,QAAM,QAAQ,KAAK;AAEnB,QAAM,QAAQ,MAAM;AACpB,QAAM,QAAQ,WAAW,KAAK;AAE9B,QAAM,YAAY,MAAM,QAAQ,MAAM;AACtC,QAAM,aAAa,MAAM,SAAS,MAAM,gBAAgB,MAAM,eAAe,MAAM;AAEnF,QAAM,QAAQ,MAAM,QAAQ,WAAW,KAAK,GAAG,QAAQ,YAAY,KAAK,CAAC;AAEzE,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO,MAC7C;AACI,SAAO,MAAM,QAAQ,KAAK,WAAW;AACzC;AAkBO,SAAS,oBAAoB,MAAM,SAC1C;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,aAAa;AAErD,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AAEjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAKrB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AAExB,UAAQ,OAAO,MAAM,YAAY,UAAU,eAAe,MAAM,YAAY,UAAU,WAAW;AAKjG,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAEhD,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,MAAM;AAE1B,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AACjE,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AAEjE,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAEhD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AAEpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AAEb,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AACvE,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AAEvE,QAAM,KAAK,SAAS,UAAU;AAC9B,QAAM,KAAK,SAAS,UAAU;AAE9B,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,QAAQ,eAAe,IAAI,MAAM,UAAU;AACjD,QAAM,cAAc,MAAM,SAAS,QAAQ,SAAS,MAAM;AAE1D,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AAEjB,QAAM,IAAI,MAAM,MAAM,aAAa,MAAM,IAAI,EAAE,CAAC;AAChD,QAAM,QAAQ,MAAM;AACpB,QAAM,QAAQ,WAAW,KAAK;AAE9B,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAE5B,QAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC9C,QAAM,WAAW,KAAK,IAAM,IAAM,KAAK;AAEvC,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAE5B,QAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC9C,QAAM,YAAY,KAAK,IAAM,IAAM,KAAK;AAExC,QAAM,iBAAiB,WAAW,MAAM,OAAO,MAAM,cAAc,QAAQ,CAAC;AAE5E,QAAM,KAAK,KAAK;AAChB,QAAM,YAAY,KAAK,IAAM,IAAM,KAAK;AAExC,MAAI,QAAQ,sBAAsB,OAClC;AACI,UAAM,cAAc;AACpB,UAAM,gBAAgB;AACtB,UAAM,eAAe;AACrB,UAAM,eAAe;AACrB,UAAM,eAAe;AAAA,EACzB;AACJ;AAEO,SAAS,sBAAsB,MAAM,SAC5C;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,aAAa;AAErD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACvF,QAAM,SAAS,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAEvF,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,IAAI,MAAM,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,WAAW,GAAG,MAAM,IAAI,EAAE,CAAC;AAC1G,QAAM,QAAQ,eAAe,OAAO,eAAe,MAAM,KAAK;AAC9D,QAAM,QAAQ,WAAW,KAAK;AAE9B,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAC5B,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAE5B,QAAM,eAAe,MAAM,gBAAgB,MAAM,eAAe,MAAM;AAEtE,QAAM,IAAI,MAAM,QAAQ,cAAc,KAAK,GAAG,QAAQ,MAAM,aAAa,KAAK,CAAC;AAC/E,QAAM,KAAK,eAAe,KAAK,MAAM,cAAc,KAAK,MAAM;AAC9D,QAAM,KAAK,eAAe,KAAK,MAAM,cAAc,KAAK,MAAM;AAE9D,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK;AAC/B,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,CAAC;AAC7D,SAAO,mBAAmB,KAAK;AACnC;AAEO,SAAS,kBAAkB,MAAM,SAAS,SACjD;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAEhB,QAAM,gBAAiB,KAAK,OAAO;AAGnC,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAM,IAAI,MAAM,MAAM,MAAM,OAAO,eAAe,OAAO,aAAa,GAAG,MAAM,WAAW,GAAG,MAAM,IAAI,EAAE,CAAC;AAC1G,QAAM,QAAQ,eAAe,OAAO,eAAe,MAAM,KAAK;AAC9D,QAAM,cAAc,MAAM,OAAO,CAAC;AAElC,QAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,QAAM,KAAK,QAAQ,IAAI,KAAK;AAG5B,MAAI,MAAM,eAAe,kBAAkB,OAC3C;AACI,UAAM,OAAO,KAAK,KAAK,MAAM;AAC7B,QAAI,UAAU,CAAC,MAAM,YAAY;AACjC,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,UAAM,eAAe,aAAa,MAAM,eAAe,SAAS,CAAC,YAAY,UAAU;AACvF,cAAU,MAAM,eAAe;AAE/B,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AAGA,MAAI,MAAM,cACV;AACI,UAAM,IAAI;AACV,UAAM,OAAO,MAAM,eAAe,WAAW;AAC7C,UAAM,YAAY,MAAM,eAAe;AACvC,UAAM,eAAe,MAAM,eAAe;AAE1C,UAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,UAAM,iBAAiB;AAEvB,UAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,UAAU;AAErB,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AACX,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AAAA,EACf;AAEA,MAAI,MAAM,aACV;AACI,UAAMC,eAAc,MAAM,OAAO,CAAC;AAGlC;AACI,YAAM,IAAIA,eAAc,MAAM;AAC9B,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAEA,YAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAI,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AAClF,YAAM,aAAa,MAAM;AACzB,YAAM,eAAe,KAAK,IAAI,aAAa,SAAS,CAAG;AACvD,gBAAU,MAAM,eAAe;AAE/B,YAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAErB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AACX,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AAAA,IACf;AAGA;AACI,YAAM,IAAI,MAAM,mBAAmBA;AACnC,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,UAAI,IAAI,GACR;AAEI,eAAO,IAAI,QAAQ;AAAA,MACvB,WACS,SACT;AACI,eAAO,QAAQ,cAAc,WAAW;AACxC,oBAAY,QAAQ,cAAc;AAClC,uBAAe,QAAQ,cAAc;AAAA,MACzC;AAEA,YAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAC1D,UAAI,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AAClF,YAAM,aAAa,MAAM;AACzB,YAAM,eAAe,KAAK,IAAI,aAAa,SAAS,CAAG;AACvD,gBAAU,MAAM,eAAe;AAE/B,YAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,UAAU;AAErB,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AACX,WAAK,SAAS,IAAI,IAAI,CAAC;AACvB,YAAM,KAAK;AAAA,IACf;AAAA,EACJ;AAGA;AACI,UAAM,QAAQ,WAAW,KAAK;AAE9B,QAAI,OAAO;AACX,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,SACJ;AACI,YAAM,IAAI,MAAM,OAAO,CAAC;AACxB,aAAO,QAAQ,cAAc,WAAW;AACxC,kBAAY,QAAQ,cAAc;AAClC,qBAAe,QAAQ,cAAc;AAAA,IACzC;AAEA,UAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK;AACtC,UAAM,KAAK,QAAQ,IAAI,KAAK;AAC5B,UAAM,OAAO,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,KAAK;AAE1D,UAAM,UAAU,CAAC,YAAY,MAAM,YAAY,OAAO,QAAQ,eAAe,MAAM;AACnF,UAAM,eAAe;AAErB,UAAM,IAAI,QAAQ,SAAS,KAAK;AAChC,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,UAAU;AAErB,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AACX,SAAK,SAAS,IAAI,IAAI,CAAC;AACvB,UAAM,KAAK;AAAA,EACf;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AACzB,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;AA2BO,SAAS,iBAAiB,MAAM,MAAM,YAAY,YACzD;AACI,UAAQ,OAAQ,KAAK,QAAQ,YAAY,aAAc;AAEvD,QAAM,QAAQ,KAAK;AAEnB,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,KAAK,iBAAiB,YAAY,KAAK,kBAAkB;AAC/D,QAAM,OAAO,eAAe,WAAW,GAAG,MAAM,UAAU;AAE1D,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,WAAW;AAEtB,OAAK,YAAY,IAAI,IAAI,IAAI,KAAK,OAAO;AAEzC,MAAI,MAAM,aACV;AACI,UAAM,QAAQ,SAAS,IAAI,MAAM,kBAAkB,IAAI;AACvD,UAAM,QAAQ,SAAS,IAAI,MAAM,kBAAkB,IAAI;AACvD,UAAM,OAAO,WAAW,IAAI;AAC5B,SAAK,YAAY,OAAO,OAAO,IAAI,KAAK,OAAO;AAC/C,SAAK,YAAY,SAAS,OAAO,KAAK,IAAI,GAAG,SAAS,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AACzF,SAAK,YAAY,SAAS,OAAO,KAAK,IAAI,GAAG,SAAS,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AAAA,EAC7F,OAEA;AACI,SAAK,YAAY,SAAS,IAAI,GAAK,IAAI,GAAG,SAAS,IAAI,GAAK,IAAI,GAAG,IAAI,KAAK,OAAO;AAAA,EACvF;AAEA,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,IAAI,KAAK,OAAO;AAChD,OAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,IAAI,KAAK,OAAO;AACpD;;;ACtqBO,SAAS,6BAA6B,SAAS,cACtD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,eAAe;AACpC;AASO,SAAS,6BAA6B,SAC7C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAaO,SAAS,8BAA8B,SAAS,eACvD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,gBAAgB,aAAa,eAAe,CAAC,OAAO,KAAK;AAC9E;AASO,SAAS,8BAA8B,SAC9C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAUO,SAAS,yBAAyB,SAAS,UAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,WAAW,KAAK,IAAI,GAAK,QAAQ;AACtD;AASO,SAAS,yBAAyB,SACzC;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAUO,SAAS,0BAA0B,SAAS,WACnD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,YAAY,KAAK,IAAI,GAAK,SAAS;AACxD;AASO,SAAS,0BAA0B,SAC1C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAaO,SAAS,iCAAiC,SAAS,kBAC1D;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AACvE,QAAM,WAAW,mBAAmB,aAAa,kBAAkB,GAAK,CAAG;AAC/E;AASO,SAAS,iCAAiC,SACjD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,aAAa;AAEvE,SAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,qBAAqB,OAAO,MAC5C;AACI,QAAM,QAAQ,QAAQ,MAAM,OAAO,KAAK,WAAW,aAAa;AAEhE,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO,MAC7C;AACI,SAAO,MAAM,QAAQ,KAAK,WAAW;AACzC;AAeO,SAAS,oBAAoB,MAAM,SAC1C;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,aAAa;AACrD,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AACjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAIrB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AACxB,UAAQ,OAAO,MAAM,YAAY,UAAU,eAAe,MAAM,YAAY,UAAU,WAAW;AAIjG,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,MAAM;AAC1B,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AACjE,UAAQ,OAAO,KAAK,eAAe,eAAe,KAAK,KAAK,KAAK;AACjE,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AACb,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AACvE,QAAM,SAAS,MAAM,YAAY,UAAU,cAAc,cAAc;AACvE,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACzG,QAAM,cAAc,MAAM,MAAM,SAAS,QAAQ,SAAS,MAAM,GAAG,MAAM,YAAY;AACrF,QAAM,aAAa,gBAAgB,SAAS,UAAU,GAAG,SAAS,UAAU,CAAC,IAAI,MAAM;AACvF,QAAM,aAAa,cAAc,MAAM,UAAU;AACjD,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AACjB,QAAM,IAAI;AAAA,IACN,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,IACnB,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,EACvB;AACA,IAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,IAAE,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AAC3C,IAAE,GAAG,IAAI,EAAE,GAAG;AACd,IAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,QAAM,aAAa,eAAe,CAAC;AACnC,QAAM,KAAK,KAAK;AAChB,QAAM,cAAc,KAAK,IAAM,IAAM,KAAK;AAE1C,MAAI,QAAQ,sBAAsB,OAClC;AACI,UAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACrC,UAAM,iBAAiB;AAAA,EAC3B;AACJ;AAEO,SAAS,sBAAsB,MAAM,SAC5C;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,QAAQ,KAAK;AAGnB,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,QAAQ,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACtF,QAAM,QAAQ,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACtF,QAAM,KAAK,eAAe,MAAM,eAAe,MAAM,OAAO;AAC5D,QAAM,KAAK,eAAe,MAAM,eAAe,MAAM,OAAO;AAC5D,QAAM,iBAAiB,SAAS,MAAM,gBAAgB,IAAI,MAAM,aAAa;AAC7E,QAAM,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM;AACxE,QAAM,iBAAiB,SAAS,MAAM,gBAAgB,IAAI,MAAM,aAAa;AAC7E,QAAM,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM;AAC5E;AAEO,SAAS,kBAAkB,MAAM,SAAS,SACjD;AACI,UAAQ,OAAO,KAAK,QAAQ,YAAY,aAAa;AACrD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACtF,QAAM,QAAQ,MAAM,UAAU,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACtF,MAAI,KAAK,MAAM;AACf,MAAI,KAAK,MAAM;AACf,MAAI,KAAK,MAAM;AACf,MAAI,KAAK,MAAM;AAGf;AACI,QAAI,oBAAoB,gBAAgB,MAAM,eAAe,MAAM,aAAa,IAAI,MAAM;AAC1F,wBAAoB,cAAc,iBAAiB;AACnD,UAAM,cAAc,QAAQ,QAAQ,MAAM,mBAAmB;AAC7D,UAAM,OAAO,KAAK;AAClB,QAAI,UAAU,CAAC,MAAM,eAAe,OAAO;AAC3C,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,UAAM,iBAAiB,aAAa,MAAM,iBAAiB,SAAS,CAAC,YAAY,UAAU;AAC3F,cAAU,MAAM,iBAAiB;AACjC,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AAGA;AACI,UAAM,KAAK,eAAe,MAAM,eAAe,MAAM,OAAO;AAC5D,UAAM,KAAK,eAAe,MAAM,eAAe,MAAM,OAAO;AAC5D,UAAM,KAAK,MAAM,MAAM,MAAM,eAAe,MAAM,aAAa,GAAG,MAAM,IAAI,EAAE,CAAC;AAC/E,UAAM,mBAAmB,MAAM,MAAM,aAAa,EAAE;AACpD,UAAM,aAAa,QAAQ,QAAQ,QAAQ,MAAM,kBAAkB,gBAAgB;AACnF,UAAM,OAAO,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,GAAG,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,CAAC;AAC7E,UAAM,IAAI,QAAQ,MAAM,YAAY,MAAM,MAAM,UAAU,CAAC;AAC3D,QAAI,UAAU,IAAI,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACnC,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,QAAQ,IAAI,MAAM;AACrC,UAAM,gBAAgB,MAAM,MAAM,eAAe,OAAO;AAExD,QAAI,gBAAgB,MAAM,aAAa,IAAI,aAAa,YACxD;AACI,YAAM,gBAAgB,YAAY,MAAM,aAAa;AACrD,YAAM,cAAc,KAAK;AACzB,YAAM,cAAc,KAAK;AAAA,IAC7B;AACA,cAAU,MAAM,MAAM,eAAe,UAAU;AAC/C,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAC9B,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAAA,EAClC;AAEA,QAAM,iBAAiB;AACvB,QAAM,kBAAkB;AACxB,QAAM,iBAAiB;AACvB,QAAM,kBAAkB;AAC5B;;;ACtUO,SAAS,uBAAuB,SAAS,QAChD;AAEI,qBAAmB,OAAO;AAC1B,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AACtE,OAAK,WAAW,UAAU,OAAO,MAAM;AAC3C;AASO,SAAS,uBAAuB,SACvC;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AAEtE,SAAO,KAAK,WAAW;AAC3B;AAUO,SAAS,4BAA4B,SAAS,OACrD;AAEI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AACtE,OAAK,WAAW,QAAQ;AAC5B;AASO,SAAS,4BAA4B,SAC5C;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AAEtE,SAAO,KAAK,WAAW;AAC3B;AAUO,SAAS,mCAAmC,SAAS,cAC5D;AAEI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AACtE,OAAK,WAAW,eAAe;AACnC;AASO,SAAS,mCAAmC,SACnD;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AAEtE,SAAO,KAAK,WAAW;AAC3B;AAYO,SAAS,yBAAyB,SAAS,UAClD;AAEI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AACtE,OAAK,WAAW,WAAW;AAC/B;AASO,SAAS,yBAAyB,SACzC;AACI,QAAM,OAAO,uBAAuB,SAAS,YAAY,aAAa;AAEtE,SAAO,KAAK,WAAW;AAC3B;AAEO,SAAS,qBAAqB,OAAO,MAC5C;AACI,QAAM,QAAQ,QAAQ,MAAM,OAAO,KAAK,WAAW,aAAa;AAEhE,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO,MAC7C;AACI,SAAO,MAAM,QAAQ,KAAK,WAAW;AACzC;AAEO,SAAS,oBAAoB,MAAM,SAC1C;AAGI,QAAM,MAAM,KAAK;AAEjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAIrB,QAAM,QAAQ,OAAO,GAAG;AAExB,QAAM,aAAa,UAAU;AAI7B,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAEhD,QAAM,cAAc,MAAM;AAI1B,QAAM,WAAW,KAAK,KAAK,KAAK,WAAW;AAE3C,OAAK,WAAW,SAAS;AACzB,OAAK,QAAQ,SAAS;AAEtB,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,cAAc;AACxE,QAAM,UAAU,eAAe,SAAS,UAAU,GAAG,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AAEzG,QAAM,iBAAiB,WAAW,MAAM,OAAO,MAAM,cAAc,QAAQ,CAAC;AAE5E,QAAM,eAAe;AACrB,QAAM,sBAAsB;AAC5B,QAAM,kBAAkB,WAAW,cAAc,qBAAqB,QAAQ,CAAC;AAE/E,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AAEpB,QAAM,IAAI;AAAA,IACN,IAAI,IAAI,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC;AAAA,IACvD,IAAI,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,GAAG,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC;AAAA,EAC3D;AAEA,QAAM,aAAa,eAAe,CAAC;AACnC,QAAM,cAAc,MAAM,SAAS,QAAQ,MAAM,OAAO;AAExD,MAAI,QAAQ,uBAAuB,OACnC;AACI,UAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACrC,UAAM,iBAAiB;AAAA,EAC3B;AACJ;AAEO,SAAS,sBAAsB,MAAM,SAC5C;AACI,OAAK,SAAS,YAAY;AAE1B,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,QAAQ,OAAO,MAAM,MAAM;AAC1C,MAAI,KAAK,OAAO,eAAe,MAAM;AACrC,MAAI,KAAK,OAAO;AAEhB,QAAM,MAAM,OAAO;AACnB,QAAM,KAAK,eAAe,KAAK,MAAM,OAAO;AAE5C,OAAK,SAAS,IAAI,IAAI,MAAM,aAAa;AACzC,QAAM,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM;AAErD,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;AAEO,SAAS,kBAAkB,MAAM,SACxC;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,QAAQ,OAAO,MAAM,MAAM;AAE1C,MAAI,KAAK,OAAO,eAAe,MAAM;AACrC,MAAI,KAAK,OAAO;AAEhB;AACI,UAAM,YAAY,MAAM,gBAAgB;AACxC,UAAM,eAAe,MAAM,gBAAgB;AAE3C,QAAI,kBAAkB,KAAK,IAAM,CAAC,KAAK,KAAK;AAC5C,sBAAkB,YAAY,kBAAkB,eAAe,MAAM;AACrE,UAAM,kBAAkB;AAExB,UAAM,KAAK;AAAA,EACf;AAEA,QAAM,aAAa,MAAM,WAAW,QAAQ;AAE5C;AACI,UAAM,MAAM,OAAO;AACnB,UAAM,KAAK,eAAe,KAAK,MAAM,OAAO;AAC5C,UAAM,OAAO,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC;AAExC,UAAM,aAAa,MAAM,MAAM,OAAO,eAAe,EAAE,GAAG,MAAM,WAAW;AAC3E,UAAM,OAAO,QAAQ,MAAM,eAAe,UAAU,UAAU;AAE9D,UAAM,YAAY,MAAM,eAAe;AACvC,UAAM,eAAe,MAAM,eAAe;AAE1C,UAAM,IAAI,QAAQ,MAAM,YAAY,MAAM,MAAM,IAAI,CAAC;AAErD,UAAM,gBAAgB,IAAI;AAAA,MACtB,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,MACtD,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,IAAC;AAE3D,UAAM,aAAa,MAAM,cAAc,MAAM;AAC7C,UAAM,cAAc,KAAK,cAAc;AACvC,UAAM,cAAc,KAAK,cAAc;AAEvC,UAAM,MAAM,SAAS,MAAM,aAAa;AAExC,QAAI,MAAM,YACV;AACI,YAAM,gBAAgB,QAAQ,YAAY,YAAY,MAAM,aAAa,CAAC;AAAA,IAC9E;AAEA,kBAAc,IAAI,MAAM,cAAc,IAAI,WAAW;AACrD,kBAAc,IAAI,MAAM,cAAc,IAAI,WAAW;AAErD,SAAK,SAAS,IAAI,IAAI,aAAa;AACnC,UAAM,KAAK,QAAQ,IAAI,aAAa;AAAA,EACxC;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;;;AC5PO,SAAS,2BAA2B,SAAS,OACpD;AAEI,MAAI,EAAE,UAAU,KAAK,KAAK,SAAS,IACnC;AACI,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AACA,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AACtE,QAAM,UAAU,cAAc;AAClC;AASO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AAEtE,SAAO,MAAM,UAAU;AAC3B;AAUO,SAAS,kCAAkC,SAAS,cAC3D;AACI,MAAI,EAAE,UAAU,YAAY,KAAK,gBAAgB,IACjD;AACI,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAChD;AACA,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AACtE,QAAM,UAAU,qBAAqB;AACzC;AASO,SAAS,kCAAkC,SAClD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AAEtE,SAAO,MAAM,UAAU;AAC3B;AAWO,SAAS,4BAA4B,SAAS,OACrD;AACI,MAAI,EAAE,UAAU,KAAK,KAAK,SAAS,IACnC;AACI,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AACA,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AACtE,QAAM,UAAU,eAAe;AACnC;AASO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AAEtE,SAAO,MAAM,UAAU;AAC3B;AAUO,SAAS,mCAAmC,SAAS,cAC5D;AACI,MAAI,EAAE,UAAU,YAAY,KAAK,gBAAgB,IACjD;AACI,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAChD;AACA,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AACtE,QAAM,UAAU,sBAAsB;AAC1C;AASO,SAAS,mCAAmC,SACnD;AACI,QAAM,QAAQ,uBAAuB,SAAS,YAAY,YAAY;AAEtE,SAAO,MAAM,UAAU;AAC3B;AAEO,SAAS,oBAAoB,OAAO,MAC3C;AACI,QAAM,QAAQ,QAAQ,MAAM,OAAO,KAAK,UAAU,aAAa;AAE/D,SAAO;AACX;AAEO,SAAS,qBAAqB,OAAO,MAC5C;AACI,SAAO,MAAM,QAAQ,KAAK,UAAU;AACxC;AAEO,SAAS,mBAAmB,MAAM,SACzC;AACI,MAAI,KAAK,SAAS,YAAY,cAC9B;AACI,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACxC;AAEA,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AAEjB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM;AAKrB,QAAM,QAAQ,OAAO,GAAG;AACxB,QAAM,QAAQ,OAAO,GAAG;AAExB,MAAI,EAAE,MAAM,aAAa,UAAU,eAAe,MAAM,aAAa,UAAU,cAC/E;AACI,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACrD;AAKA,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAChD,QAAM,OAAO,MAAM,eAAe,MAAM,QAAQ;AAEhD,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,MAAM;AAE1B,MAAI,EAAE,KAAK,eAAe,eAAe,KAAK,KAAK,QACnD;AACI,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AAEA,MAAI,EAAE,KAAK,eAAe,eAAe,KAAK,KAAK,QACnD;AACI,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AAEA,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAChD,QAAM,WAAW,KAAK,KAAK,KAAK,MAAM,UAAU;AAEhD,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,SAAS;AAEpB,OAAK,WAAW;AAChB,OAAK,WAAW;AAChB,OAAK,QAAQ;AACb,OAAK,QAAQ;AAEb,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,cAAc;AACxE,QAAM,SAAS,MAAM,aAAa,UAAU,cAAc,cAAc;AAExE,QAAM,KAAK,SAAS,UAAU;AAC9B,QAAM,KAAK,SAAS,UAAU;AAE9B,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,UAAU,eAAe,IAAI,MAAM,KAAK,oBAAoB,SAAS,WAAW,CAAC;AACvF,QAAM,cAAc,MAAM,SAAS,QAAQ,SAAS,MAAM;AAC1D,QAAM,aAAa,gBAAgB,IAAI,EAAE,IAAI,MAAM;AAEnD,QAAM,KAAK,KAAK;AAChB,QAAM,YAAY,KAAK,IAAM,IAAM,KAAK;AAExC,MAAI,MAAM,gBAAgB,GAC1B;AACI,UAAM,iBAAiB,QAAQ;AAAA,EACnC,OAEA;AACI,UAAM,iBAAiB,WAAW,MAAM,aAAa,MAAM,oBAAoB,QAAQ,CAAC;AAAA,EAC5F;AAEA,MAAI,MAAM,iBAAiB,GAC3B;AACI,UAAM,kBAAkB,QAAQ;AAAA,EACpC,OAEA;AACI,UAAM,kBAAkB,WAAW,MAAM,cAAc,MAAM,qBAAqB,QAAQ,CAAC;AAAA,EAC/F;AAEA,MAAI,QAAQ,uBAAuB,OACnC;AACI,UAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACrC,UAAM,iBAAiB;AAAA,EAC3B;AACJ;AAEO,SAAS,qBAAqB,MAAM,SAC3C;AACI,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,QAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,MAAM,aAAa;AAC/E,SAAO,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM;AAEzE,SAAO,iBAAiB,SAAS,OAAO,gBAAgB,IAAI,MAAM,aAAa;AAC/E,SAAO,mBAAmB,MAAM,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM;AAC7E;AAEO,SAAS,iBAAiB,MAAM,SAAS,SAChD;AACI,MAAI,KAAK,SAAS,YAAY,cAC9B;AACI,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACxC;AAEA,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAGhB,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,QAAQ,KAAK;AAEnB,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AACxF,QAAM,SAAS,MAAM,WAAW,gBAAgB,aAAa,QAAQ,OAAO,MAAM,MAAM;AAExF,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAGhB;AACI,QAAI,OAAO;AACX,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,WAAW,MAAM,eAAe,GACpC;AACI,YAAM,IAAI,gBAAgB,OAAO,eAAe,OAAO,aAAa,IAAI,MAAM;AAC9E,aAAO,MAAM,gBAAgB,WAAW;AACxC,kBAAY,MAAM,gBAAgB;AAClC,qBAAe,MAAM,gBAAgB;AAAA,IACzC;AAEA,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,CAAC,YAAY,MAAM,aAAa,OAAO,QAAQ,eAAe,MAAM;AACpF,UAAM,kBAAkB;AAExB,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AAGA;AACI,UAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAC7D,UAAM,KAAK,eAAe,OAAO,eAAe,MAAM,OAAO;AAE7D,QAAI,OAAO,IAAI,OAAO,GAAG,CAAC;AAC1B,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,WAAW,MAAM,cAAc,GACnC;AACI,YAAM,MAAM,OAAO;AACnB,YAAM,MAAM,OAAO;AACnB,YAAM,IAAI,MAAM,MAAM,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC,GAAG,MAAM,WAAW;AAExE,aAAO,QAAQ,MAAM,eAAe,UAAU,CAAC;AAC/C,kBAAY,MAAM,eAAe;AACjC,qBAAe,MAAM,eAAe;AAAA,IACxC;AAEA,UAAM,OAAO,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,GAAG,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,CAAC;AAE7E,UAAM,IAAI,IAAI,QAAQ;AACtB,MAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,MAAE,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AAC3C,MAAE,GAAG,IAAI,EAAE,GAAG;AACd,MAAE,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;AACpD,UAAM,IAAI,UAAU,GAAG,MAAM,MAAM,IAAI,CAAC;AAExC,UAAM,UAAU,IAAI;AAAA,MAChB,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,MACtD,CAAC,YAAY,EAAE,IAAI,eAAe,MAAM,cAAc;AAAA,IAAC;AAE3D,UAAM,gBAAgB,MAAM,MAAM,eAAe,OAAO;AAExD,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAC9B,SAAK,SAAS,IAAI,IAAI,OAAO;AAC7B,UAAM,KAAK,QAAQ,IAAI,OAAO;AAAA,EAClC;AAEA,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AACzB,SAAO,iBAAiB;AACxB,SAAO,kBAAkB;AAC7B;;;ACnVO,SAAS,4BAChB;AACI,QAAM,MAAM,IAAI,mBAAmB;AACnC,MAAI,SAAS;AACb,MAAI,YAAY;AAEhB,SAAO;AACX;AAiBO,SAAS,yBAChB;AACI,QAAM,MAAM,IAAI,gBAAgB;AAChC,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,MAAI,mBAAmB;AAEvB,SAAO;AACX;AAaO,SAAS,yBAChB;AACI,QAAM,MAAM,IAAI,gBAAgB;AAChC,MAAI,QAAQ;AACZ,MAAI,eAAe;AACnB,MAAI,WAAW;AAEf,SAAO;AACX;AAWO,SAAS,6BAChB;AACI,QAAM,MAAM,IAAI,oBAAoB;AACpC,MAAI,aAAa,IAAI,OAAO,GAAK,CAAG;AAEpC,SAAO;AACX;AAUO,SAAS,4BAChB;AACI,QAAM,MAAM,IAAI,mBAAmB;AACnC,MAAI,WAAW;AAEf,SAAO;AACX;AAeO,SAAS,wBAChB;AACI,SAAO,IAAI,eAAe;AAC9B;AAeO,SAAS,yBAChB;AACI,QAAM,MAAM,IAAI,gBAAgB;AAChC,MAAI,aAAa,IAAI,OAAO,GAAK,CAAG;AACpC,MAAI,eAAe;AACnB,MAAI,QAAQ;AACZ,MAAI,eAAe;AAEnB,SAAO;AACX;AAEA,SAAS,iBAAiB,OAAO,SACjC;AACI,QAAM,KAAK,QAAQ,SAAS;AAG5B,QAAM,QAAQ,MAAM,WAAW,EAAE;AAGjC,UAAQ,OAAO,MAAM,aAAa,QAAQ,QAAQ;AAElD,SAAO;AACX;AAEO,SAAS,WAAW,OAAO,SAClC;AAEI,SAAO,MAAM,WAAW,OAAO;AACnC;AAEO,SAAS,cAAc,OAAO,OACrC;AAGI,MAAI,MAAM,aAAa,UAAU,aACjC;AAEI,UAAM,QAAQ,MAAM,gBAAgB,OAAO,MAAM,UAAU;AAI3D,QAAI,MAAM,YAAY,MAAM,OAAO,KAAK,MAAM,UAAU,EAAE,SAC1D;AACI,cAAQ,MAAM,aAAa,MAAM,UAAU,iBAAkB,MAAM,aAAa,uBAAuB,MAAM,OAAO,KAAK,MAAM,UAAU,EAAE,OAAO;AAAA,IAGtJ;AAEA,WAAO,MAAM,OAAO,KAAK,MAAM,UAAU;AAAA,EAC7C;AAEA,QAAM,MAAM,MAAM,eAAe,MAAM,QAAQ;AAC/C,UAAQ,OAAO,KAAK,MAAM,cAAc,MAAM,aAAa,IAAI,OAAO,KAAK;AAC3E,UAAQ,OAAO,MAAM,WAAW,IAAI,OAAO,KAAK,MAAM,UAAU,EAAE,OAAO;AAEzE,SAAO,IAAI,OAAO,KAAK,MAAM,UAAU;AAC3C;AAEO,SAAS,uBAAuB,SAAS,MAChD;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,UAAQ,OAAO,MAAM,SAAS,IAAI;AAClC,QAAM,WAAW,cAAc,OAAO,KAAK;AAC3C,UAAQ,OAAO,SAAS,SAAS,IAAI;AAErC,SAAO;AACX;AAEA,IAAM,cAAN,MACA;AAAA,EACI,YAAY,QAAQ,MAAM,WAAW,MACrC;AACI,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EAEpB;AACJ;AAEO,SAAS,cAAc,OAAO,OAAO,OAAO,UAAU,UAAU,MAAM,kBAC7E;AAEI,uBAAqB,KAAK;AAE1B,QAAM,UAAU,MAAM;AACtB,QAAM,UAAU,MAAM;AACtB,QAAM,cAAc,KAAK,IAAI,MAAM,UAAU,MAAM,QAAQ;AAG3D,QAAM,UAAU,UAAU,MAAM,WAAW;AAC3C,UAAQ,OAAO,WAAW,aAAa;AAGvC,SAAO,WAAW,MAAM,WAAW,QACnC;AACI,UAAM,WAAW,KAAK,IAAI,QAAQ,CAAC;AAAA,EACvC;AAEA,QAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,QAAM,QAAQ,CAAE,IAAI,YAAY,GAAG,IAAI,YAAY,CAAE;AACrD,QAAM,UAAU;AAChB,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,YAAY;AAClB,QAAM,WAAW;AACjB,QAAM,OAAO;AACb,QAAM,WAAW;AACjB,QAAM,mBAAmB;AAGzB,QAAM,MAAM,CAAC,EAAE,SAAS;AACxB,QAAM,MAAM,CAAC,EAAE,UAAU;AACzB,QAAM,MAAM,CAAC,EAAE,UAAU,MAAM;AAE/B,QAAM,OAAQ,WAAW,IAAK;AAE9B,MAAI,MAAM,iBAAiB,eAC3B;AACI,UAAM,SAAS,MAAM,WAAW,MAAM,gBAAgB,CAAC;AACvD,UAAM,QAAQ,OAAO,MAAM,MAAM,eAAe,CAAC;AACjD,UAAM,UAAU;AAAA,EACpB;AACA,QAAM,eAAe;AACrB,QAAM,cAAc;AAKpB,QAAM,MAAM,CAAC,EAAE,SAAS;AACxB,QAAM,MAAM,CAAC,EAAE,UAAU;AACzB,QAAM,MAAM,CAAC,EAAE,UAAU,MAAM;AAE/B,QAAM,OAAQ,WAAW,IAAK;AAE9B,MAAI,MAAM,iBAAiB,eAC3B;AACI,UAAM,SAAS,MAAM,WAAW,MAAM,gBAAgB,CAAC;AACvD,UAAM,QAAQ,OAAO,MAAM,MAAM,eAAe,CAAC;AACjD,UAAM,UAAU;AAAA,EACpB;AACA,QAAM,eAAe;AACrB,QAAM,cAAc;AAIpB,MAAI;AAEJ,MAAI,MAAM,aAAa,UAAU,kBAAkB,MAAM,aAAa,UAAU,gBAChF;AAEI,UAAM,MAAM,MAAM,eAAe,UAAU,cAAc;AACzD,UAAM,WAAW,UAAU;AAC3B,UAAM,aAAa,IAAI,OAAO;AAE9B,eAAW,WAAW,IAAI,MAAM;AAChC,aAAS,UAAU;AAGnB,aAAS,UAAU;AACnB,aAAS,UAAU;AAAA,EACvB,WACS,MAAM,aAAa,UAAU,gBAAgB,MAAM,aAAa,UAAU,cACnF;AAEI,UAAM,MAAM,MAAM,eAAe,UAAU,YAAY;AACvD,UAAM,WAAW,UAAU;AAC3B,UAAM,aAAa,IAAI,OAAO;AAE9B,eAAW,WAAW,IAAI,MAAM;AAChC,aAAS,UAAU;AAGnB,aAAS,UAAU;AACnB,aAAS,UAAU;AAAA,EACvB,WACS,MAAM,aAAa,UAAU,eAAe,MAAM,aAAa,UAAU,aAClF;AAEI,QAAI,eAAe,UAAU,qBAC7B;AAEI,sBAAgB,OAAO,WAAW;AAAA,IACtC;AAEA,UAAM,WAAW,UAAU;AAE3B,eAAW,qBAAqB,OAAO,KAAK;AAC5C,aAAS,UAAU;AAGnB,aAAS,UAAU;AACnB,aAAS,UAAU;AAAA,EACvB,OAEA;AAEI,YAAQ,OAAO,MAAM,YAAY,UAAU,uBAAuB,MAAM,YAAY,UAAU,mBAAmB;AACjH,YAAQ,OAAO,MAAM,aAAa,UAAU,gBAAgB,MAAM,aAAa,UAAU,YAAY;AAGrG,QAAI,WAAW;AAGf,UAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,UAAM,WAAW;AACjB,UAAM,aAAa,IAAI,OAAO;AAC9B,eAAW,WAAW,IAAI,MAAM;AAChC,aAAS,UAAU;AAGnB,aAAS,UAAU;AACnB,aAAS,UAAU;AAEnB,QAAI,MAAM,aAAa,MAAM,YAAY,MAAM,YAAY,UAAU,uBACjE,MAAM,YAAY,UAAU,qBAChC;AAEI,wBAAkB,OAAO,MAAM,UAAU,MAAM,QAAQ;AACvD,cAAQ,OAAO,MAAM,aAAa,MAAM,QAAQ;AAGhD,iBAAW,MAAM;AAGjB,iBAAW,MAAM,eAAe,QAAQ,EAAE,OAAO,MAAM,UAAU;AAAA,IACrE;AAEA,YAAQ,OAAO,MAAM,aAAa,QAAQ;AAAA,EAC9C;AAEA,UAAQ,OAAO,SAAS,YAAY,OAAO;AAC3C,UAAQ,OAAO,SAAS,YAAY,OAAO;AAC3C,UAAQ,OAAO,SAAS,YAAY,OAAO;AAE3C,MAAI,MAAM,WAAW,UAAU,gBAC/B;AAEI,gBAAY,OAAO,KAAK;AAAA,EAC5B;AAEA,uBAAqB,KAAK;AAE1B,SAAO,IAAI,YAAY,OAAO,QAAQ;AAC1C;AAIO,SAAS,+BAA+B,OAAO,OAAO,OAC7D;AACI,MAAI;AACJ,MAAI;AAEJ,MAAI,MAAM,eAAe,MAAM,cAC/B;AACI,iBAAa,MAAM;AACnB,kBAAc,MAAM;AAAA,EACxB,OAEA;AACI,iBAAa,MAAM;AACnB,kBAAc,MAAM;AAAA,EACxB;AAEA,QAAM,aAAa;AAEnB,SAAO,eAAe,eACtB;AACI,UAAM,YAAY,cAAc;AAChC,UAAM,YAAY,aAAa;AAG/B,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,iBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,UAAM,iBAAiB,YAAY;AAEnC,QAAI,QAAQ,MAAM,cAAc,EAAE,WAAW,aAC7C;AAEI,uBAAiB,OAAO,SAAS,UAAU;AAAA,IAC/C;AAAA,EACJ;AAEA,uBAAqB,KAAK;AAC9B;AA0BO,SAAS,sBAAsB,SAAS,KAC/C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,UAAQ,OAAO,eAAe,IAAI,OAAO,CAAC;AAC1C,UAAQ,OAAO,eAAe,IAAI,OAAO,CAAC;AAC1C,UAAQ,OAAO,UAAU,IAAI,MAAM,KAAK,IAAI,SAAS,CAAG;AAExD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,kBAAkB,IAAI,gBAAgB;AAErH,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,qBAAqB,IAAI;AAE/B,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,QAAM,cAAc,SAAS,KAAK,IAAI,IAAI,QAAQ,aAAa;AAC/D,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,cAAc,YAAY,KAAK,IAAI,IAAI,WAAW,aAAa;AACrE,QAAM,cAAc,YAAY,KAAK,IAAI,IAAI,WAAW,IAAI,SAAS;AACrE,QAAM,cAAc,gBAAgB,IAAI;AACxC,QAAM,cAAc,aAAa,IAAI;AACrC,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,cAAc,cAAc,IAAI;AACtC,QAAM,cAAc,cAAc,IAAI;AACtC,QAAM,cAAc,UAAU;AAC9B,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,eAAe;AAEnC,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AAmBO,SAAS,mBAAmB,SAAS,KAC5C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,eAAe,IAAI,gBAAgB;AAClH,QAAM,QAAQ,KAAK;AAEnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI,OAAO,GAAG,CAAC;AAC1C,QAAM,qBAAqB,IAAI,OAAO,GAAG,CAAC;AAC1C,QAAM,aAAa,IAAI,aAAa;AACpC,QAAM,WAAW,eAAe,IAAI;AACpC,QAAM,WAAW,gBAAgB,IAAI;AACrC,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,WAAW,mBAAmB,aAAa,IAAI,kBAAkB,GAAK,CAAG;AAE/E,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AAsBO,SAAS,mBAAmB,SAAS,KAC5C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,aAAa,wBAAwB,OAAO,KAAK;AACvD,QAAM,aAAa,wBAAwB,OAAO,KAAK;AAEvD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,eAAe,IAAI,gBAAgB;AAElH,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,oBAAoB,YAAY,IAAI,MAAM;AACrE,QAAM,qBAAqB,oBAAoB,YAAY,IAAI,MAAM;AAErE,QAAM,aAAa,IAAI,aAAa;AACpC,QAAM,WAAW,UAAU,IAAI;AAC/B,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,WAAW,eAAe,IAAI;AACpC,QAAM,WAAW,WAAW,IAAI;AAEhC,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AA2BO,SAAS,sBAAsB,SAAS,KAC/C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,IAAI,UAAU,YAAY,kBAAkB,IAAI,gBAAgB;AAE9H,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,qBAAqB,IAAI;AAE/B,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,QAAM,cAAc,iBAAiB,aAAa,IAAI,gBAAgB,CAAC,KAAK,IAAI,KAAK,EAAE;AACvF,QAAM,cAAc,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACnD,QAAM,cAAc,YAAY;AAChC,QAAM,cAAc,gBAAgB;AACpC,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,cAAc,aAAa,KAAK,IAAI,IAAI,YAAY,IAAI,UAAU;AACxE,QAAM,cAAc,aAAa,KAAK,IAAI,IAAI,YAAY,IAAI,UAAU;AACxE,QAAM,cAAc,aAAa,aAAa,MAAM,cAAc,YAAY,CAAC,KAAK,IAAI,KAAK,EAAE;AAC/F,QAAM,cAAc,aAAa,aAAa,MAAM,cAAc,YAAY,CAAC,KAAK,IAAI,KAAK,EAAE;AAC/F,QAAM,cAAc,iBAAiB,IAAI;AACzC,QAAM,cAAc,aAAa,IAAI;AACrC,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,cAAc,cAAc,IAAI;AACtC,QAAM,cAAc,cAAc,IAAI;AAEtC,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AA4BO,SAAS,uBAAuB,SAAS,KAChD;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,mBAAmB,IAAI,gBAAgB;AAEtH,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,qBAAqB,IAAI;AAE/B,QAAM,iBAAiB,IAAI,iBAAiB;AAC5C,QAAM,eAAe,aAAa,YAAY,IAAI,UAAU;AAC5D,QAAM,eAAe,iBAAiB,IAAI;AAC1C,QAAM,eAAe,UAAU,IAAI,OAAO,GAAG,CAAC;AAC9C,QAAM,eAAe,YAAY;AACjC,QAAM,eAAe,gBAAgB;AACrC,QAAM,eAAe,eAAe;AACpC,QAAM,eAAe,eAAe;AACpC,QAAM,eAAe,eAAe;AACpC,QAAM,eAAe,QAAQ,IAAI;AACjC,QAAM,eAAe,eAAe,IAAI;AACxC,QAAM,eAAe,mBAAmB,IAAI;AAC5C,QAAM,eAAe,mBAAmB,IAAI;AAC5C,QAAM,eAAe,gBAAgB,IAAI;AACzC,QAAM,eAAe,aAAa,IAAI;AACtC,QAAM,eAAe,eAAe,IAAI;AACxC,QAAM,eAAe,cAAc,IAAI;AACvC,QAAM,eAAe,cAAc,IAAI;AAEvC,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AAqBO,SAAS,kBAAkB,SAAS,KAC3C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,cAAc,IAAI,gBAAgB;AAEjH,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,qBAAqB,IAAI;AAE/B,QAAM,YAAY,IAAI,YAAY;AAClC,QAAM,UAAU,iBAAiB,IAAI;AACrC,QAAM,UAAU,cAAc,IAAI;AAClC,QAAM,UAAU,qBAAqB,IAAI;AACzC,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,UAAU,sBAAsB,IAAI;AAC1C,QAAM,UAAU,gBAAgB,IAAI,OAAO,GAAG,CAAC;AAC/C,QAAM,UAAU,iBAAiB;AAEjC,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AAcO,SAAS,mBAAmB,SAAS,KAC5C;AAEI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,UAAU;AAAA,EACzB;AAEA,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAChD,QAAM,QAAQ,gBAAgB,OAAO,IAAI,OAAO;AAEhD,QAAM,OAAO,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU,GAAK,YAAY,eAAe,IAAI,gBAAgB;AAElH,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,YAAY;AACzB,QAAM,qBAAqB,IAAI;AAC/B,QAAM,qBAAqB,IAAI;AAE/B,QAAM,aAAa,IAAI,aAAa;AACpC,QAAM,WAAW,aAAa,YAAY,IAAI,UAAU;AACxD,QAAM,WAAW,WAAW;AAC5B,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,eAAe;AAChC,QAAM,WAAW,eAAe;AAChC,QAAM,WAAW,eAAe;AAChC,QAAM,WAAW,mBAAmB,IAAI;AACxC,QAAM,WAAW,mBAAmB,IAAI;AACxC,QAAM,WAAW,iBAAiB,IAAI;AACtC,QAAM,WAAW,aAAa,IAAI;AAClC,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,WAAW,eAAe,IAAI;AACpC,QAAM,WAAW,eAAe,IAAI;AACpC,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,WAAW,cAAc,IAAI;AAEnC,MAAI,IAAI,qBAAqB,OAC7B;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AAEA,QAAM,UAAU,IAAI,UAAU,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,MAAM,QAAQ;AAEnF,SAAO;AACX;AAEO,SAAS,uBAAuB,OAAO,OAAO,YACrD;AACI,QAAM,UAAU,MAAM;AAEtB,QAAM,QAAQ,MAAM,MAAM,CAAC;AAC3B,QAAM,QAAQ,MAAM,MAAM,CAAC;AAE3B,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAM,QAAQ,UAAU,OAAO,GAAG;AAClC,QAAM,QAAQ,UAAU,OAAO,GAAG;AAGlC,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,YAAY,MAAM,WAAW,MAAM,WAAW,CAAC;AACrD,UAAM,WAAW,UAAU,MAAM,MAAM,UAAU,CAAC;AAClD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,YAAY,MAAM,WAAW,MAAM,WAAW,CAAC;AACrD,UAAM,WAAW,UAAU,MAAM,MAAM,UAAU,CAAC;AAClD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,QAAM,WAAY,WAAW,IAAK;AAElC,MAAI,MAAM,iBAAiB,UAC3B;AACI,UAAM,eAAe,MAAM;AAAA,EAC/B;AAEA,QAAM,cAAc;AAGpB,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,YAAY,MAAM,WAAW,MAAM,WAAW,CAAC;AACrD,UAAM,WAAW,UAAU,MAAM,MAAM,UAAU,CAAC;AAClD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,YAAY,MAAM,WAAW,MAAM,WAAW,CAAC;AACrD,UAAM,WAAW,UAAU,MAAM,MAAM,UAAU,CAAC;AAClD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,QAAM,WAAY,WAAW,IAAK;AAElC,MAAI,MAAM,iBAAiB,UAC3B;AACI,UAAM,eAAe,MAAM;AAAA,EAC/B;AAEA,QAAM,cAAc;AAEpB,gBAAc,OAAO,KAAK;AAG1B,QAAM,WAAW,MAAM;AACvB,QAAM,aAAa,MAAM;AAEzB,MAAI,aAAa,UAAU,aAC3B;AACI,2BAAuB,OAAO,MAAM,MAAM,CAAC,EAAE,QAAQ,MAAM,MAAM,CAAC,EAAE,QAAQ,MAAM,YAAY,UAAU;AAAA,EAC5G,OAEA;AACI,UAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,UAAM,aAAa,cAAc,IAAI,QAAQ,UAAU;AAEvD,QAAI,eAAe,eACnB;AAEI,YAAM,gBAAgB,IAAI,OAAO,KAAK,UAAU;AAChD,YAAM,UAAU,cAAc;AAC9B,YAAM,aAAa,MAAM,WAAW,OAAO;AAC3C,cAAQ,OAAO,WAAW,eAAe,UAAU;AACnD,iBAAW,aAAa;AAAA,IAC5B;AAAA,EACJ;AAGA,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,UAAU;AAChB,QAAM,OAAO,YAAY;AACzB,WAAS,MAAM,aAAa,OAAO;AAEnC,MAAI,YACJ;AACI,eAAW,OAAO,KAAK;AACvB,eAAW,OAAO,KAAK;AAAA,EAC3B;AAEA,uBAAqB,KAAK;AAC9B;AAYO,SAAS,eAAe,SAC/B;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,yBAAuB,OAAO,OAAO,IAAI;AAC7C;AAYO,SAAS,gBAAgB,SAChC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,SAAO,MAAM;AACjB;AAYO,SAAS,iBAAiB,SACjC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,SAAO,aAAa,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AACpD;AAYO,SAAS,iBAAiB,SACjC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,SAAO,aAAa,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AACpD;AAWO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,WAAW,cAAc,OAAO,KAAK;AAE3C,SAAO,SAAS;AACpB;AAWO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,WAAW,cAAc,OAAO,KAAK;AAE3C,SAAO,SAAS;AACpB;AAcO,SAAS,4BAA4B,SAAS,eACrD;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,MAAI,MAAM,qBAAqB,eAC/B;AACI;AAAA,EACJ;AAEA,QAAM,mBAAmB;AAEzB,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AACpD,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AAEpD,MAAI,eACJ;AAGI,UAAM,cAAc,MAAM;AAC1B,UAAM,cAAc,MAAM;AAE1B,QAAI,UAAU,cAAc,cAAc,MAAM,cAAc,MAAM;AAEpE,WAAO,YAAY,eACnB;AACI,YAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,UAAI,MAAM,aAAa,eACvB;AACI,qBAAa,MAAM,YAAY,MAAM,QAAQ;AAAA,MACjD;AAEA,gBAAU,MAAM;AAAA,IACpB;AAAA,EACJ,OAEA;AACI,mCAA+B,OAAO,OAAO,KAAK;AAAA,EACtD;AACJ;AAUO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,SAAO,MAAM;AACjB;AAaO,SAAS,oBAAoB,SAAS,UAC7C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,WAAW;AACrB;AAaO,SAAS,oBAAoB,SACpC;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAE7C,SAAO,MAAM;AACjB;AAUO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,iBAAiB,QAAQ,MAAM;AAE7C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AACnD,QAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AAEnD,aAAW,OAAO,KAAK;AACvB,aAAW,OAAO,KAAK;AAC3B;AAsBO,SAAS,2BAA2B,SAC3C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,OAAO,cAAc,OAAO,KAAK;AAEvC,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO,wBAAwB,OAAO,IAAI;AAAA,IAE9C,KAAK,YAAY;AACb,aAAO,qBAAqB,OAAO,IAAI;AAAA,IAE3C,KAAK,YAAY;AACb,aAAO,qBAAqB,OAAO,IAAI;AAAA,IAE3C,KAAK,YAAY;AACb,aAAO,yBAAyB,OAAO,IAAI;AAAA,IAE/C,KAAK,YAAY;AACb,aAAO,wBAAwB,OAAO,IAAI;AAAA,IAE9C,KAAK,YAAY;AACb,aAAO,oBAAoB,OAAO,IAAI;AAAA,IAE1C,KAAK,YAAY;AACb,aAAO,qBAAqB,OAAO,IAAI;AAAA,IAE3C;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,EAC9B;AACJ;AAoBO,SAAS,4BAA4B,SAC5C;AACI,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,QAAM,QAAQ,iBAAiB,OAAO,OAAO;AAC7C,QAAM,OAAO,cAAc,OAAO,KAAK;AAEvC,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,aAAO;AAAA,IAEX,KAAK,YAAY;AACb,aAAO,sBAAsB,OAAO,IAAI;AAAA,IAE5C,KAAK,YAAY;AACb,aAAO,sBAAsB,OAAO,IAAI;AAAA,IAE5C,KAAK,YAAY;AACb,aAAO,0BAA0B,OAAO,IAAI;AAAA,IAEhD,KAAK,YAAY;AACb,aAAO,yBAAyB,OAAO,IAAI;AAAA,IAE/C,KAAK,YAAY;AACb,aAAO,qBAAqB,OAAO,IAAI;AAAA,IAE3C,KAAK,YAAY;AACb,aAAO,sBAAsB,OAAO,IAAI;AAAA,IAE5C;AACI,cAAQ,OAAO,KAAK;AAEpB,aAAO;AAAA,EACf;AACJ;AAEO,SAAS,eAAe,OAAO,SACtC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,6BAAuB,OAAO,OAAO;AAErC;AAAA,IAEJ,KAAK,YAAY;AACb,0BAAoB,OAAO,OAAO;AAElC;AAAA,IAEJ,KAAK,YAAY;AACb,0BAAoB,OAAO,OAAO;AAElC;AAAA,IAEJ,KAAK,YAAY;AACb,8BAAwB,OAAO,OAAO;AAEtC;AAAA,IAEJ,KAAK,YAAY;AACb,6BAAuB,OAAO,OAAO;AAErC;AAAA,IAEJ,KAAK,YAAY;AACb,yBAAmB,OAAO,OAAO;AAEjC;AAAA,IAEJ,KAAK,YAAY;AACb,0BAAoB,OAAO,OAAO;AAElC;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAAA,EAC5B;AACJ;AAEO,SAAS,iBAAiB,OAAO,SACxC;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,+BAAyB,OAAO,OAAO;AAEvC;AAAA,IAEJ,KAAK,YAAY;AACb,4BAAsB,OAAO,OAAO;AAEpC;AAAA,IAEJ,KAAK,YAAY;AACb,4BAAsB,OAAO,OAAO;AAEpC;AAAA,IAEJ,KAAK,YAAY;AACb,gCAA0B,OAAO,OAAO;AAExC;AAAA,IAEJ,KAAK,YAAY;AACb,+BAAyB,OAAO,OAAO;AAEvC;AAAA,IAEJ,KAAK,YAAY;AACb,2BAAqB,OAAO,OAAO;AAEnC;AAAA,IAEJ,KAAK,YAAY;AACb,4BAAsB,OAAO,OAAO;AAEpC;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAAA,EAC5B;AACJ;AAEO,SAAS,aAAa,OAAO,SAAS,SAC7C;AACI,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb,2BAAqB,OAAO,SAAS,OAAO;AAE5C;AAAA,IAEJ,KAAK,YAAY;AACb,wBAAkB,OAAO,SAAS,OAAO;AAEzC;AAAA,IAEJ,KAAK,YAAY;AACb,wBAAkB,OAAO,OAAO;AAEhC;AAAA,IAEJ,KAAK,YAAY;AACb,4BAAsB,OAAO,SAAS,OAAO;AAE7C;AAAA,IAEJ,KAAK,YAAY;AACb,2BAAqB,OAAO,SAAS,OAAO;AAE5C;AAAA,IAEJ,KAAK,YAAY;AACb,uBAAiB,OAAO,SAAS,OAAO;AAExC;AAAA,IAEJ,KAAK,YAAY;AACb,wBAAkB,OAAO,SAAS,OAAO;AAEzC;AAAA,IAEJ;AACI,cAAQ,OAAO,KAAK;AAAA,EAC5B;AACJ;AAEO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM,OAAO,gBAAgB,EAAE,OAAO;AACrD,QAAM,aAAa,MAAM,OAAO,gBAAgB,EAAE,OAAO;AAEzD,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,UAAM,QAAQ,OAAO,CAAC;AACtB,mBAAe,OAAO,OAAO;AAAA,EACjC;AACJ;AAEO,SAAS,0BAA0B,SAC1C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM,OAAO,gBAAgB,EAAE,OAAO;AACrD,QAAM,aAAa,MAAM,OAAO,gBAAgB,EAAE,OAAO;AAEzD,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,UAAM,QAAQ,OAAO,CAAC;AACtB,qBAAiB,OAAO,OAAO;AAAA,EACnC;AACJ;AAEO,SAAS,sBAAsB,SAAS,SAC/C;AACI,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM,OAAO,gBAAgB,EAAE,OAAO;AACrD,QAAM,aAAa,MAAM,OAAO,gBAAgB,EAAE,OAAO;AAEzD,WAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,UAAM,QAAQ,OAAO,CAAC;AACtB,iBAAa,OAAO,SAAS,OAAO;AAAA,EACxC;AACJ;AAEO,SAAS,YAAY,MAAM,OAAO,OACzC;AACI,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AACpD,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AAEpD,MAAI,MAAM,aAAa,UAAU,kBAAkB,MAAM,aAAa,UAAU,gBAChF;AACI;AAAA,EACJ;AAEA,QAAM,WAAW,cAAc,OAAO,KAAK;AAC3C,UAAQ,OAAO,QAAQ;AAEvB,QAAM,aAAa,wBAAwB,OAAO,KAAK;AACvD,QAAM,aAAa,wBAAwB,OAAO,KAAK;AACvD,QAAM,KAAK,iBAAiB,YAAY,SAAS,kBAAkB;AACnE,QAAM,KAAK,iBAAiB,YAAY,SAAS,kBAAkB;AAEnE,QAAM,QAAQ,WAAW;AAEzB,UAAQ,MAAM,MACd;AAAA,IAEI,KAAK,YAAY;AACb,0BAAoB,MAAM,UAAU,YAAY,UAAU;AAE1D;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,SAAS,SAAS,WAAW;AAEnC,cAAM,KAAK,WAAW;AACtB,aAAK,UAAU,OAAO,GAAG,OAAO,GAAG,GAAK,IAAI,KAAK,OAAO;AACxD,aAAK,UAAU,GAAG,GAAG,GAAG,GAAG,GAAK,IAAI,KAAK,OAAO;AAEhD,cAAM,KAAK,WAAW;AACtB,aAAK,YAAY,QAAQ,IAAI,IAAI,KAAK,OAAO;AAAA,MACjD;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb,2BAAqB,MAAM,UAAU,YAAY,UAAU;AAE3D;AAAA,IAEJ,KAAK,YAAY;AACb,0BAAoB,MAAM,UAAU,YAAY,YAAY,MAAM,QAAQ;AAE1E;AAAA,IAEJ,KAAK,YAAY;AACb,uBAAiB,MAAM,UAAU,YAAY,UAAU;AAEvD;AAAA,IAEJ;AACI,WAAK,YAAY,WAAW,GAAG,IAAI,OAAO,KAAK,OAAO;AACtD,WAAK,YAAY,IAAI,IAAI,OAAO,KAAK,OAAO;AAC5C,WAAK,YAAY,WAAW,GAAG,IAAI,OAAO,KAAK,OAAO;AAAA,EAC9D;AAEA,MAAI,KAAK,iBACT;AACI,UAAM,SAAS;AAAA,MAAE,WAAW;AAAA,MAAa,WAAW;AAAA,MAAgB,WAAW;AAAA,MAAgB,WAAW;AAAA,MACtG,WAAW;AAAA,MAAc,WAAW;AAAA,MAAc,WAAW;AAAA,MAAgB,WAAW;AAAA,MACxF,WAAW;AAAA,MAAmB,WAAW;AAAA,MAAmB,WAAW;AAAA,MAAe,WAAW;AAAA,IAAc;AAEnH,UAAM,aAAa,MAAM;AAEzB,QAAI,eAAe,eACnB;AACI,YAAMC,KAAI,OAAO,IAAI,IAAI,GAAG;AAC5B,WAAK,UAAUA,GAAE,GAAGA,GAAE,GAAG,GAAK,OAAO,UAAU,GAAG,KAAK,OAAO;AAAA,IAClE;AAAA,EACJ;AACJ;;;AC7lDO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,EACnB;AACJ;AAEO,IAAM,UAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,QAAQ,CAAE,IAAI,YAAY,GAAG,IAAI,YAAY,CAAE;AACpD,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,OAAO,YAAY;AACxB,SAAK,WAAW;AAChB,SAAK,mBAAmB;AAAA,EAC5B;AACJ;AAEO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,mBAAmB,IAAI,WAAW;AACvC,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,iBAAgB;AAC/B,OAAG,SAAS,KAAK;AACjB,OAAG,QAAQ,KAAK;AAChB,OAAG,eAAe,KAAK;AACvB,OAAG,YAAY,KAAK;AACpB,OAAG,YAAY,KAAK;AACpB,OAAG,gBAAgB,KAAK;AACxB,OAAG,aAAa,KAAK;AACrB,OAAG,UAAU,KAAK;AAClB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,mBAAmB,KAAK;AAC3B,OAAG,YAAY,KAAK;AACpB,OAAG,eAAe,KAAK;AACvB,OAAG,cAAc,KAAK;AACtB,OAAG,cAAc,KAAK;AAEtB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,eAAN,MAAM,cACb;AAAA,EACI,cACA;AACI,SAAK,eAAe,IAAI,OAAO;AAC/B,SAAK,gBAAgB;AACrB,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,iBAAiB;AACtB,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,mBAAmB;AACxB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,aAAa;AAClB,SAAK,aAAa,IAAI,QAAQ;AAC9B,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,cAAa;AAC5B,OAAG,eAAe,KAAK,aAAa,MAAM;AAC1C,OAAG,gBAAgB,KAAK;AACxB,OAAG,gBAAgB,KAAK,cAAc,MAAM;AAC5C,OAAG,iBAAiB,KAAK;AACzB,OAAG,WAAW,KAAK;AACnB,OAAG,YAAY,KAAK;AACpB,OAAG,mBAAmB,KAAK;AAC3B,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,aAAa,KAAK;AACrB,OAAG,aAAa,KAAK,WAAW,MAAM;AACtC,OAAG,cAAc,KAAK;AAEtB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,eAAN,MAAM,cACb;AAAA,EACI,cACA;AACI,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,iBAAiB;AACtB,SAAK,iBAAiB,IAAI,WAAW;AACrC,SAAK,kBAAkB,IAAI,WAAW;AACtC,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,aAAa,IAAI,QAAQ;AAAA,EAClC;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,cAAa;AAC5B,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,QAAQ,KAAK;AAChB,OAAG,eAAe,KAAK;AACvB,OAAG,WAAW,KAAK;AACnB,OAAG,gBAAgB,KAAK,cAAc,MAAM;AAC5C,OAAG,iBAAiB,KAAK;AACzB,OAAG,iBAAiB,KAAK;AACzB,OAAG,kBAAkB,KAAK;AAC1B,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,aAAa,KAAK,WAAW,MAAM;AAEtC,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,mBAAN,MAAM,kBACb;AAAA,EACI,cACA;AACI,SAAK,aAAa,IAAI,OAAO;AAC7B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,QAAQ,IAAI,OAAO;AACxB,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,iBAAiB,IAAI,WAAW;AACrC,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,kBAAiB;AAChC,OAAG,aAAa,KAAK,WAAW,MAAM;AACtC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,gBAAgB,KAAK;AACxB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,QAAQ,KAAK;AAChB,OAAG,eAAe,KAAK;AACvB,OAAG,gBAAgB,KAAK;AACxB,OAAG,aAAa,KAAK;AACrB,OAAG,iBAAiB,KAAK;AACzB,OAAG,mBAAmB,KAAK;AAC3B,OAAG,mBAAmB,KAAK;AAC3B,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,QAAQ,KAAK,MAAM,MAAM;AAC5B,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,aAAa,KAAK;AACrB,OAAG,YAAY,KAAK;AACpB,OAAG,iBAAiB,KAAK,eAAe,MAAM;AAC9C,OAAG,eAAe,KAAK;AACvB,OAAG,cAAc,KAAK;AACtB,OAAG,cAAc,KAAK;AAEtB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,kBAAN,MAAM,iBACb;AAAA,EACI,cACA;AACI,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,iBAAiB,IAAI,WAAW;AACrC,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,iBAAgB;AAC/B,OAAG,gBAAgB,KAAK,cAAc,MAAM;AAC5C,OAAG,gBAAgB,KAAK;AACxB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,QAAQ,KAAK;AAChB,OAAG,eAAe,KAAK;AACvB,OAAG,iBAAiB,KAAK;AACzB,OAAG,aAAa,KAAK;AACrB,OAAG,iBAAiB,KAAK;AACzB,OAAG,aAAa,KAAK;AACrB,OAAG,aAAa,KAAK;AACrB,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,aAAa,KAAK;AACrB,OAAG,YAAY,KAAK;AACpB,OAAG,iBAAiB,KAAK;AACzB,OAAG,eAAe,KAAK;AACvB,OAAG,cAAc,KAAK;AACtB,OAAG,cAAc,KAAK;AAEtB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,cAAN,MAAM,aACb;AAAA,EACI,cACA;AACI,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,qBAAqB;AAC1B,SAAK,eAAe;AACpB,SAAK,sBAAsB;AAC3B,SAAK,iBAAiB,IAAI,WAAW;AACrC,SAAK,kBAAkB,IAAI,WAAW;AACtC,SAAK,gBAAgB,IAAI,OAAO;AAChC,SAAK,iBAAiB;AACtB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,aAAa;AAClB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,aAAY;AAC3B,OAAG,iBAAiB,KAAK;AACzB,OAAG,cAAc,KAAK;AACtB,OAAG,qBAAqB,KAAK;AAC7B,OAAG,eAAe,KAAK;AACvB,OAAG,sBAAsB,KAAK;AAC9B,OAAG,iBAAiB,KAAK;AACzB,OAAG,kBAAkB,KAAK;AAC1B,OAAG,gBAAgB,KAAK,cAAc,MAAM;AAC5C,OAAG,iBAAiB,KAAK;AACzB,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,aAAa,KAAK;AACrB,OAAG,YAAY,KAAK;AAEpB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,eAAN,MAAM,cACb;AAAA,EACI,cACA;AACI,SAAK,aAAa,IAAI,OAAO;AAC7B,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,QAAQ,IAAI,OAAO;AACxB,SAAK,cAAc,IAAI,OAAO;AAC9B,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,iBAAiB,IAAI,WAAW;AACrC,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,QACA;AACI,UAAM,KAAK,IAAI,cAAa;AAC5B,OAAG,aAAa,KAAK,WAAW,MAAM;AACtC,OAAG,cAAc,KAAK;AACtB,OAAG,eAAe,KAAK;AACvB,OAAG,gBAAgB,KAAK;AACxB,OAAG,eAAe,KAAK;AACvB,OAAG,eAAe,KAAK;AACvB,OAAG,iBAAiB,KAAK;AACzB,OAAG,aAAa,KAAK;AACrB,OAAG,mBAAmB,KAAK;AAC3B,OAAG,mBAAmB,KAAK;AAC3B,OAAG,QAAQ,KAAK;AAChB,OAAG,eAAe,KAAK;AACvB,OAAG,SAAS,KAAK;AACjB,OAAG,SAAS,KAAK;AACjB,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,UAAU,KAAK,QAAQ,MAAM;AAChC,OAAG,QAAQ,KAAK,MAAM,MAAM;AAC5B,OAAG,cAAc,KAAK,YAAY,MAAM;AACxC,OAAG,WAAW,KAAK;AACnB,OAAG,YAAY,KAAK;AACpB,OAAG,YAAY,KAAK;AACpB,OAAG,iBAAiB,KAAK;AACzB,OAAG,eAAe,KAAK;AACvB,OAAG,cAAc,KAAK;AACtB,OAAG,cAAc,KAAK;AAEtB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,aAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,OAAO,YAAY;AACxB,SAAK,qBAAqB,IAAI,OAAO;AACrC,SAAK,qBAAqB,IAAI,OAAO;AACrC,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,QAAQ;AAIb,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,YAAY;AACjB,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,OAAO,KACP;AACI,QAAI,UAAU,KAAK;AACnB,QAAI,UAAU,KAAK;AACnB,QAAI,UAAU,KAAK;AACnB,QAAI,OAAO,KAAK;AAChB,QAAI,qBAAqB,KAAK,mBAAmB,MAAM;AACvD,QAAI,qBAAqB,KAAK,mBAAmB,MAAM;AACvD,QAAI,WAAW,KAAK;AACpB,QAAI,WAAW,KAAK;AACpB,QAAI,QAAQ,KAAK;AACjB,QAAI,QAAQ,KAAK;AACjB,QAAI,QAAQ,KAAK;AACjB,QAAI,gBAAiB,KAAK,gBAAgB,KAAK,cAAc,MAAM,IAAI;AACvE,QAAI,aAAc,KAAK,aAAa,KAAK,WAAW,MAAM,IAAI;AAC9D,QAAI,aAAc,KAAK,aAAa,KAAK,WAAW,MAAM,IAAI;AAC9D,QAAI,gBAAiB,KAAK,gBAAgB,KAAK,cAAc,MAAM,IAAI;AACvE,QAAI,iBAAkB,KAAK,iBAAiB,KAAK,eAAe,MAAM,IAAI;AAC1E,QAAI,YAAa,KAAK,YAAY,KAAK,UAAU,MAAM,IAAI;AAC3D,QAAI,aAAc,KAAK,aAAa,KAAK,WAAW,MAAM,IAAI;AAAA,EAClE;AACJ;;;ACtbO,IAAM,WAAN,MACP;AAAA,EACI,WAAW;AAAA,EACX,aAAa;AAAA,EACb,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AAAA,EACf,wBAAwB;AAC5B;AAEO,IAAM,cAAN,MACP;AAAA,EACI,WAAW;AACf;AAEO,SAAS,eAAe,OAAO,UACtC;AACI,UAAQ,OAAO,aAAa,UAAU,eAAe,YAAY,UAAU,mBAAmB;AAE9F,QAAM,WAAW,UAAU,MAAM,YAAY;AAE7C,MAAI,aAAa,MAAM,YAAY,QACnC;AACI,UAAM,cAAc,IAAI,SAAS;AACjC,gBAAY,WAAW;AACvB,UAAM,YAAY,KAAK,WAAW;AAAA,EACtC,OAEA;AACI,YAAQ,OAAO,MAAM,YAAY,QAAQ,EAAE,aAAa,aAAa;AAAA,EACzE;AAGA,QAAM,MAAM,MAAM,eAAe,QAAQ;AAEzC,QAAM,SAAS,MAAM,YAAY,QAAQ;AACzC,SAAO,WAAW;AAClB,SAAO,aAAa,IAAI,QAAQ;AAChC,SAAO,WAAW;AAClB,SAAO,WAAW;AAClB,SAAO,WAAW;AAClB,SAAO,YAAY;AACnB,SAAO,cAAc;AACrB,SAAO,cAAc;AACrB,SAAO,eAAe;AACtB,SAAO,YAAY;AACnB,SAAO,YAAY;AACnB,SAAO,aAAa;AACpB,SAAO,eAAe;AACtB,SAAO,wBAAwB;AAE/B,QAAM,YAAY,YAAY,IAAI,OAAO;AACzC,YAAU,WAAW;AAErB,SAAO;AACX;AAEO,SAAS,gBAAgB,OAAO,UACvC;AAEI,QAAM,SAAS,MAAM,YAAY,QAAQ;AAGzC,QAAM,MAAM,MAAM,eAAe,OAAO,QAAQ;AAChD,QAAM,aAAa,eAAe,IAAI,SAAS,OAAO,UAAU;AAEhE,MAAI,eAAe,eACnB;AACI,UAAM,eAAe,IAAI,QAAQ,KAAK,OAAO,UAAU;AACvD,UAAM,UAAU,aAAa;AAC7B,UAAM,cAAc,MAAM,YAAY,OAAO;AAC7C,YAAQ,OAAO,YAAY,eAAe,UAAU;AACpD,gBAAY,aAAa,OAAO;AAAA,EACpC;AAEA,SAAO,WAAW;AAClB,SAAO,WAAW;AAClB,SAAO,aAAa;AACpB,WAAS,MAAM,cAAc,QAAQ;AACzC;AAEO,SAAS,YAAY,OAAO,UACnC;AAEI,SAAO,MAAM,YAAY,QAAQ;AACrC;AAEA,SAAS,qBAAqB,OAAO,UAAU,SAC/C;AACI,UAAQ,OAAO,QAAQ,aAAa,aAAa;AACjD,UAAQ,OAAO,QAAQ,eAAe,aAAa;AACnD,UAAQ,OAAO,QAAQ,eAAe,aAAa;AAGnD,QAAM,SAAS,MAAM,YAAY,QAAQ;AAEzC,MAAI,OAAO,gBAAgB,eAC3B;AACI,YAAQ,aAAa,OAAO;AAG5B,UAAM,cAAc,MAAM,aAAa,OAAO,WAAW;AACzD,gBAAY,aAAa,QAAQ;AAAA,EACrC;AAEA,SAAO,cAAc,QAAQ;AAE7B,MAAI,OAAO,gBAAgB,eAC3B;AACI,WAAO,cAAc,OAAO;AAAA,EAChC;AAEA,SAAO,gBAAgB;AACvB,UAAQ,WAAW;AAEnB,mBAAiB,OAAO,QAAQ;AACpC;AAEO,SAAS,cAAc,OAAO,SACrC;AACI,UAAQ,QAAQ,QAAQ,QAAQ,eAAe,4BAA4B,MAAM,QAAQ,QAAQ,eAAe,0BAA0B,CAAC;AAE3I,QAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,QAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AAEjC,QAAM,QAAQ,UAAU,OAAO,OAAO;AACtC,QAAM,QAAQ,UAAU,OAAO,OAAO;AAEtC,UAAQ,OAAO,MAAM,aAAa,UAAU,kBAAkB,MAAM,aAAa,UAAU,cAAc;AACzG,UAAQ,OAAO,MAAM,aAAa,UAAU,gBAAgB,MAAM,aAAa,UAAU,YAAY;AAErG,MAAI,MAAM,aAAa,UAAU,eAAe,MAAM,YAAY,UAAU,qBAC5E;AACI,oBAAgB,OAAO,MAAM,QAAQ;AAAA,EACzC;AAEA,MAAI,MAAM,aAAa,UAAU,eAAe,MAAM,YAAY,UAAU,qBAC5E;AACI,oBAAgB,OAAO,MAAM,QAAQ;AAAA,EACzC;AAEA,MAAI,YAAY,MAAM;AACtB,MAAI,YAAY,MAAM;AAEtB,UAAQ,OAAO,MAAM,aAAa,UAAU,gBAAgB,cAAc,aAAa;AACvF,UAAQ,OAAO,MAAM,aAAa,UAAU,gBAAgB,cAAc,aAAa;AACvF,UAAQ,OAAO,cAAc,iBAAiB,cAAc,aAAa;AAEzE,MAAI,cAAc,WAClB;AACI,yBAAqB,OAAO,WAAW,OAAO;AAE9C;AAAA,EACJ;AAEA,MAAI,UAAU;AAEd,MAAI,cAAc,eAClB;AACI,cAAU,YAAY,OAAO,SAAS;AACtC,QAAI,WAAW,QAAQ;AAEvB,WAAO,aAAa,eACpB;AACI,YAAM,SAAS,YAAY,OAAO,QAAQ;AAE1C,UAAI,OAAO,iBAAiB,eAC5B;AACI,gBAAQ,eAAe,OAAO;AAAA,MAClC;AAEA,gBAAU;AACV,kBAAY;AACZ,iBAAW,QAAQ;AAAA,IACvB;AAAA,EACJ;AAEA,MAAI,UAAU;AAEd,MAAI,cAAc,eAClB;AACI,cAAU,YAAY,OAAO,SAAS;AACtC,QAAI,WAAW,QAAQ;AAEvB,WAAO,QAAQ,iBAAiB,eAChC;AACI,YAAM,SAAS,YAAY,OAAO,QAAQ;AAE1C,UAAI,OAAO,iBAAiB,eAC5B;AACI,gBAAQ,eAAe,OAAO;AAAA,MAClC;AAEA,gBAAU;AACV,kBAAY;AACZ,iBAAW,QAAQ;AAAA,IACvB;AAAA,EACJ;AAEA,UAAQ,OAAO,YAAY,QAAQ,YAAY,IAAI;AAEnD,MAAI,YAAY,WAAW,YAAY,QAAQ,YAAY,MAC3D;AACI,YAAQ,OAAO,YAAY,OAAO;AAClC,YAAQ,OAAO,QAAQ,iBAAiB,aAAa;AACrD,YAAQ,eAAe;AAAA,EAC3B;AAEA,MAAI,YAAY,MAChB;AACI,yBAAqB,OAAO,WAAW,OAAO;AAAA,EAClD,OAEA;AACI,yBAAqB,OAAO,WAAW,OAAO;AAAA,EAClD;AACJ;AAEO,SAAS,gBAAgB,OAAO,SACvC;AACI,UAAQ,QAAQ,QAAQ,QAAQ,eAAe,0BAA0B,CAAC;AAC1E,UAAQ,OAAO,QAAQ,aAAa,aAAa;AAEjD,QAAM,WAAW,QAAQ;AAGzB,QAAM,SAAS,YAAY,OAAO,QAAQ;AAE1C,MAAI,QAAQ,eAAe,eAC3B;AAEI,UAAM,cAAc,MAAM,aAAa,QAAQ,UAAU;AACzD,YAAQ,OAAO,YAAY,eAAe,QAAQ,SAAS;AAC3D,gBAAY,aAAa,QAAQ;AAAA,EACrC;AAEA,MAAI,QAAQ,eAAe,eAC3B;AAEI,UAAM,cAAc,MAAM,aAAa,QAAQ,UAAU;AACzD,YAAQ,OAAO,YAAY,eAAe,QAAQ,SAAS;AAC3D,gBAAY,aAAa,QAAQ;AAAA,EACrC;AAEA,MAAI,OAAO,gBAAgB,QAAQ,WACnC;AACI,WAAO,cAAc,QAAQ;AAAA,EACjC;AAEA,MAAI,OAAO,gBAAgB,QAAQ,WACnC;AACI,WAAO,cAAc,QAAQ;AAAA,EACjC;AAEA,UAAQ,OAAO,OAAO,eAAe,CAAC;AACtC,SAAO,gBAAgB;AACvB,SAAO,yBAAyB;AAEhC,UAAQ,WAAW;AACnB,UAAQ,aAAa;AACrB,UAAQ,aAAa;AAErB,mBAAiB,OAAO,QAAQ;AACpC;AAEA,SAAS,mBAAmB,OAAO,UAAU,OAC7C;AACI,UAAQ,OAAO,MAAM,aAAa,aAAa;AAC/C,UAAQ,OAAO,MAAM,eAAe,aAAa;AACjD,UAAQ,OAAO,MAAM,eAAe,aAAa;AAGjD,QAAM,SAAS,MAAM,YAAY,QAAQ;AAEzC,MAAI,OAAO,cAAc,eACzB;AACI,UAAM,aAAa,OAAO;AAC1B,UAAM,YAAY,WAAW,OAAO,OAAO,SAAS;AACpD,cAAU,aAAa,MAAM;AAAA,EACjC;AAEA,SAAO,YAAY,MAAM;AAEzB,MAAI,OAAO,cAAc,eACzB;AACI,WAAO,YAAY,OAAO;AAAA,EAC9B;AAEA,SAAO,cAAc;AACrB,QAAM,WAAW;AAEjB,mBAAiB,OAAO,QAAQ;AACpC;AAEO,SAAS,YAAY,OAAO,OACnC;AACI,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AACpD,QAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE,MAAM;AAEpD,MAAI,MAAM,aAAa,UAAU,eAAe,MAAM,YAAY,UAAU,qBAC5E;AACI,oBAAgB,OAAO,MAAM,QAAQ;AAAA,EACzC,WACS,MAAM,aAAa,UAAU,eAAe,MAAM,YAAY,UAAU,qBACjF;AACI,oBAAgB,OAAO,MAAM,QAAQ;AAAA,EACzC;AAEA,MAAI,YAAY,MAAM;AACtB,MAAI,YAAY,MAAM;AAEtB,UAAQ,OAAO,cAAc,iBAAiB,cAAc,aAAa;AAEzE,MAAI,cAAc,WAClB;AACI,uBAAmB,OAAO,WAAW,KAAK;AAE1C;AAAA,EACJ;AAEA,MAAI,UAAU;AAEd,MAAI,cAAc,eAClB;AACI,cAAU,YAAY,OAAO,SAAS;AAEtC,WAAO,QAAQ,iBAAiB,eAChC;AACI,YAAM,SAAS,YAAY,OAAO,QAAQ,YAAY;AAEtD,UAAI,OAAO,iBAAiB,eAC5B;AACI,gBAAQ,eAAe,OAAO;AAAA,MAClC;AAEA,kBAAY,QAAQ;AACpB,gBAAU;AAAA,IACd;AAAA,EACJ;AAEA,MAAI,UAAU;AAEd,MAAI,cAAc,eAClB;AACI,cAAU,YAAY,OAAO,SAAS;AAEtC,WAAO,QAAQ,iBAAiB,eAChC;AACI,YAAM,SAAS,YAAY,OAAO,QAAQ,YAAY;AAEtD,UAAI,OAAO,iBAAiB,eAC5B;AACI,gBAAQ,eAAe,OAAO;AAAA,MAClC;AAEA,kBAAY,QAAQ;AACpB,gBAAU;AAAA,IACd;AAAA,EACJ;AAEA,UAAQ,OAAO,YAAY,QAAQ,YAAY,IAAI;AAEnD,MAAI,YAAY,WAAW,YAAY,QAAQ,YAAY,MAC3D;AACI,YAAQ,OAAO,YAAY,OAAO;AAClC,YAAQ,OAAO,QAAQ,iBAAiB,aAAa;AACrD,YAAQ,eAAe;AAAA,EAC3B;AAEA,MAAI,YAAY,MAChB;AACI,uBAAmB,OAAO,WAAW,KAAK;AAAA,EAC9C,OAEA;AACI,uBAAmB,OAAO,WAAW,KAAK;AAAA,EAC9C;AACJ;AAEO,SAAS,cAAc,OAAO,OACrC;AACI,UAAQ,OAAO,MAAM,aAAa,aAAa;AAE/C,QAAM,WAAW,MAAM;AAGvB,QAAM,SAAS,MAAM,YAAY,QAAQ;AAEzC,MAAI,MAAM,eAAe,eACzB;AACI,UAAM,YAAY,WAAW,OAAO,MAAM,UAAU;AACpD,YAAQ,OAAO,UAAU,eAAe,MAAM,OAAO;AACrD,cAAU,aAAa,MAAM;AAAA,EACjC;AAEA,MAAI,MAAM,eAAe,eACzB;AACI,UAAM,YAAY,WAAW,OAAO,MAAM,UAAU;AACpD,YAAQ,OAAO,UAAU,eAAe,MAAM,OAAO;AACrD,cAAU,aAAa,MAAM;AAAA,EACjC;AAEA,MAAI,OAAO,cAAc,MAAM,SAC/B;AACI,WAAO,YAAY,MAAM;AAAA,EAC7B;AAEA,MAAI,OAAO,cAAc,MAAM,SAC/B;AACI,WAAO,YAAY,MAAM;AAAA,EAC7B;AAEA,UAAQ,OAAO,OAAO,aAAa,CAAC;AACpC,SAAO,cAAc;AACrB,SAAO,yBAAyB;AAEhC,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,aAAa;AAEnB,mBAAiB,OAAO,QAAQ;AACpC;AAEA,SAAS,cAAc,OAAO,QAC9B;AACI,UAAQ,OAAO,OAAO,iBAAiB,aAAa;AAEpD,QAAM,SAAS,OAAO;AAGtB,QAAM,aAAa,MAAM,YAAY,MAAM;AAC3C,UAAQ,OAAO,WAAW,iBAAiB,aAAa;AAExD,MAAI,SAAS,OAAO;AAEpB,SAAO,WAAW,eAClB;AACI,UAAM,OAAO,UAAU,OAAO,MAAM;AACpC,SAAK,WAAW;AAChB,aAAS,KAAK;AAAA,EAClB;AAEA,MAAI,YAAY,OAAO;AAEvB,SAAO,cAAc,eACrB;AAEI,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,YAAQ,WAAW;AACnB,gBAAY,QAAQ;AAAA,EACxB;AAEA,MAAI,UAAU,OAAO;AAErB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAM,WAAW;AACjB,cAAU,MAAM;AAAA,EACpB;AAEA,UAAQ,OAAO,WAAW,aAAa,aAAa;AACpD,QAAM,WAAW,UAAU,OAAO,WAAW,QAAQ;AACrD,UAAQ,OAAO,SAAS,eAAe,aAAa;AACpD,WAAS,aAAa,OAAO;AAE7B,UAAQ,OAAO,OAAO,aAAa,aAAa;AAChD,QAAM,WAAW,UAAU,OAAO,OAAO,QAAQ;AACjD,UAAQ,OAAO,SAAS,eAAe,aAAa;AACpD,WAAS,aAAa,WAAW;AAEjC,aAAW,WAAW,OAAO;AAC7B,aAAW,aAAa,OAAO;AAE/B,MAAI,WAAW,gBAAgB,eAC/B;AACI,YAAQ,OAAO,WAAW,gBAAgB,iBAAiB,WAAW,iBAAiB,CAAC;AACxF,eAAW,cAAc,OAAO;AAChC,eAAW,cAAc,OAAO;AAChC,eAAW,eAAe,OAAO;AAAA,EACrC,WACS,OAAO,gBAAgB,eAChC;AACI,YAAQ,OAAO,OAAO,gBAAgB,iBAAiB,OAAO,eAAe,CAAC;AAC9E,YAAQ,OAAO,WAAW,gBAAgB,iBAAiB,WAAW,eAAe,CAAC;AAGtF,UAAM,cAAc,MAAM,aAAa,WAAW,WAAW;AAC7D,YAAQ,OAAO,YAAY,eAAe,aAAa;AACvD,gBAAY,aAAa,OAAO;AAGhC,UAAM,cAAc,MAAM,aAAa,OAAO,WAAW;AACzD,YAAQ,OAAO,YAAY,eAAe,aAAa;AACvD,gBAAY,aAAa,WAAW;AAEpC,eAAW,cAAc,OAAO;AAChC,eAAW,gBAAgB,OAAO;AAAA,EACtC;AAEA,MAAI,WAAW,cAAc,eAC7B;AACI,YAAQ,OAAO,WAAW,cAAc,iBAAiB,WAAW,eAAe,CAAC;AACpF,eAAW,YAAY,OAAO;AAC9B,eAAW,YAAY,OAAO;AAC9B,eAAW,aAAa,OAAO;AAAA,EACnC,WACS,OAAO,cAAc,eAC9B;AACI,YAAQ,OAAO,OAAO,cAAc,iBAAiB,OAAO,aAAa,CAAC;AAC1E,YAAQ,OAAO,WAAW,cAAc,iBAAiB,WAAW,aAAa,CAAC;AAElF,UAAM,YAAY,WAAW,OAAO,WAAW,SAAS;AACxD,YAAQ,OAAO,UAAU,eAAe,aAAa;AACrD,cAAU,aAAa,OAAO;AAE9B,UAAM,YAAY,WAAW,OAAO,OAAO,SAAS;AACpD,YAAQ,OAAO,UAAU,eAAe,aAAa;AACrD,cAAU,aAAa,WAAW;AAElC,eAAW,YAAY,OAAO;AAC9B,eAAW,cAAc,OAAO;AAAA,EACpC;AAEA,aAAW,yBAAyB,OAAO;AAE3C,mBAAiB,OAAO,MAAM;AAClC;AAEO,SAAS,oBAAoB,OACpC;AAGI,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAC3D,QAAM,aAAa,SAAS,QAAQ;AACpC,QAAM,mBAAmB,SAAS,QAAQ;AAC1C,QAAM,UAAU,MAAM;AAEtB,WAAS,IAAI,GAAG,IAAI,kBAAkB,EAAE,GACxC;AACI,UAAM,WAAW,WAAW,CAAC,EAAE;AAG/B,UAAM,SAAS,QAAQ,QAAQ;AAE/B,QAAI,SAAS;AACb,QAAI,aAAa;AAEjB,WAAO,WAAW,iBAAiB,eACnC;AAEI,YAAM,SAAS,QAAQ,WAAW,YAAY;AAE9C,UAAI,OAAO,iBAAiB,eAC5B;AACI,mBAAW,eAAe,OAAO;AAAA,MACrC;AAEA,eAAS,WAAW;AACpB,mBAAa;AAAA,IACjB;AAEA,QAAI,eAAe,QACnB;AACI,aAAO,eAAe;AAAA,IAC1B;AAAA,EACJ;AAEA,WAAS,IAAI,mBAAmB,GAAG,KAAK,GAAG,EAAE,GAC7C;AACI,UAAM,WAAW,WAAW,CAAC,EAAE;AAG/B,UAAM,SAAS,QAAQ,QAAQ;AAE/B,QAAI,OAAO,iBAAiB,eAC5B;AACI;AAAA,IACJ;AAEA,kBAAc,OAAO,MAAM;AAE3B,oBAAgB,OAAO,QAAQ;AAAA,EACnC;AAEA,yBAAuB,KAAK;AAGhC;AAEO,SAAS,cAAc,OAAO,QACrC;AAEI,QAAM,aAAa,MAAM,YAAY,MAAM;AAC3C,QAAM,WAAW,WAAW;AAE5B,MAAI,aAAa,UAAU,aAC3B;AAEI;AAAA,EACJ;AAEA,MAAI,WAAW,0BAA0B,GACzC;AAEI;AAAA,EACJ;AAEA,mBAAiB,OAAO,MAAM;AAE9B,QAAM,YAAY,WAAW;AAE7B,QAAM,SAAS,MAAM;AACrB,QAAM,WAAW,MAAM;AAEvB,QAAMC,SAAQ,CAAC;AACf,QAAM,UAAU,CAAC;AAIjB,MAAI,WAAW,WAAW;AAE1B,SAAO,aAAa,eACpB;AACI,YAAQ,KAAK,QAAQ;AACrB,UAAM,OAAO,OAAO,QAAQ;AAG5B,SAAK,WAAW;AAEhB,eAAW,KAAK;AAAA,EACpB;AACA,UAAQ,OAAO,QAAQ,WAAW,SAAS;AAI3C,MAAI,gBAAgB,WAAW;AAE/B,SAAO,kBAAkB,eACzB;AACI,UAAM,UAAU,SAAS,aAAa;AACtC,YAAQ,WAAW;AACnB,oBAAgB,QAAQ;AAAA,EAC5B;AAGA,MAAI,YAAY,WAAW;AAE3B,SAAO,cAAc,eACrB;AACI,UAAM,QAAQ,WAAW,OAAO,SAAS;AACzC,UAAM,WAAW;AACjB,gBAAY,MAAM;AAAA,EACtB;AAGA,kBAAgB,OAAO,MAAM;AAG7B,WAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,UAAM,YAAY,QAAQ,CAAC;AAC3B,UAAM,OAAO,OAAO,SAAS;AAC7B,YAAQ,OAAO,KAAK,aAAa,QAAQ;AAEzC,QAAI,KAAK,aAAa,MACtB;AACI;AAAA,IACJ;AAEA,IAAAA,OAAM,KAAK,SAAS;AACpB,SAAK,WAAW;AAEhB,UAAM,SAAS,eAAe,OAAO,QAAQ;AAE7C,UAAM,WAAW,OAAO;AAExB,WAAOA,OAAM,SAAS,GACtB;AACI,YAAM,SAASA,OAAM,IAAI;AACzB,YAAM,OAAO,OAAO,MAAM;AAC1B,cAAQ,OAAO,KAAK,aAAa,UAAU,WAAW;AACtD,cAAQ,OAAO,KAAK,aAAa,IAAI;AAErC,WAAK,WAAW;AAEhB,UAAI,OAAO,aAAa,eACxB;AACI,eAAO,OAAO,QAAQ,EAAE,aAAa;AAAA,MACzC;AACA,WAAK,aAAa,OAAO;AACzB,WAAK,aAAa;AAClB,aAAO,WAAW;AAElB,UAAI,OAAO,aAAa,eACxB;AACI,eAAO,WAAW;AAAA,MACtB;AAEA,aAAO,aAAa;AAEpB,UAAI,aAAa,KAAK;AAEtB,aAAO,eAAe,eACtB;AACI,cAAM,YAAY,cAAc;AAChC,cAAM,YAAY,aAAa;AAG/B,cAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,gBAAQ,OAAO,QAAQ,cAAc,SAAS;AAE9C,qBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,YAAI,QAAQ,UACZ;AACI;AAAA,QACJ;AAEA,YAAI,QAAQ,QAAQ,eAAe,sBACnC;AACI;AAAA,QACJ;AAEA,aAAK,QAAQ,QAAQ,eAAe,4BAA4B,GAChE;AACI;AAAA,QACJ;AAEA,gBAAQ,WAAW;AAEnB,cAAM,iBAAiB,YAAY;AACnC,cAAM,cAAc,QAAQ,MAAM,cAAc,EAAE;AAClD,cAAM,YAAY,OAAO,WAAW;AAEpC,YAAI,UAAU,aAAa,SAAS,UAAU,aAAa,UAAU,cACrE;AACI,kBAAQ,OAAOA,OAAM,SAAS,SAAS;AACvC,UAAAA,OAAM,KAAK,WAAW;AACtB,oBAAU,WAAW;AAAA,QACzB;AAEA,gBAAQ,WAAW;AAEnB,YAAI,OAAO,gBAAgB,eAC3B;AAEI,gBAAM,cAAc,MAAM,aAAa,OAAO,WAAW;AACzD,sBAAY,aAAa;AAAA,QAC7B;AACA,gBAAQ,aAAa,OAAO;AAC5B,gBAAQ,aAAa;AACrB,eAAO,cAAc;AAErB,YAAI,OAAO,gBAAgB,eAC3B;AACI,iBAAO,cAAc;AAAA,QACzB;AAEA,eAAO,gBAAgB;AAAA,MAC3B;AAEA,UAAI,WAAW,KAAK;AAEpB,aAAO,aAAa,eACpB;AACI,cAAM,UAAU,YAAY;AAC5B,cAAM,YAAY,WAAW;AAE7B,cAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,gBAAQ,OAAO,MAAM,YAAY,OAAO;AAExC,mBAAW,MAAM,MAAM,SAAS,EAAE;AAElC,YAAI,MAAM,UACV;AACI;AAAA,QACJ;AAEA,cAAM,WAAW;AAEjB,cAAM,iBAAiB,YAAY;AACnC,cAAM,cAAc,MAAM,MAAM,cAAc,EAAE;AAChD,cAAM,YAAY,OAAO,WAAW;AAEpC,YAAI,UAAU,aAAa,UAAU,gBACrC;AACI;AAAA,QACJ;AAEA,YAAI,UAAU,aAAa,SAAS,UAAU,aAAa,UAAU,aACrE;AACI,UAAAA,OAAM,KAAK,WAAW;AACtB,oBAAU,WAAW;AAAA,QACzB;AAEA,cAAM,WAAW;AAEjB,YAAI,OAAO,cAAc,eACzB;AACI,gBAAM,YAAY,WAAW,OAAO,OAAO,SAAS;AACpD,oBAAU,aAAa;AAAA,QAC3B;AACA,cAAM,aAAa,OAAO;AAC1B,cAAM,aAAa;AACnB,eAAO,YAAY;AAEnB,YAAI,OAAO,cAAc,eACzB;AACI,iBAAO,YAAY;AAAA,QACvB;AAEA,eAAO,cAAc;AAAA,MACzB;AAAA,IACJ;AAEA,qBAAiB,OAAO,QAAQ;AAAA,EACpC;AAIJ;AAEO,SAAS,iBAAiB,OAAO,UACxC;AACI,MAAI,CAAC,cAAc;AAAE;AAAA,EAAQ;AAE7B,eAAa,MAAM,aAAa,QAAQ;AACxC,QAAM,SAAS,MAAM,YAAY,QAAQ;AACzC,UAAQ,OAAO,OAAO,YAAY,QAAQ;AAC1C,UAAQ,OAAO,OAAO,YAAY,aAAa;AAC/C,UAAQ,OAAO,OAAO,YAAY,aAAa;AAE/C;AACI,UAAM,SAAS,MAAM;AACrB,YAAQ,OAAO,OAAO,YAAY,aAAa;AAC/C,YAAQ,OAAO,OAAO,YAAY,CAAC;AAEnC,QAAI,OAAO,YAAY,GACvB;AACI,cAAQ,OAAO,OAAO,YAAY,OAAO,QAAQ;AAAA,IACrD;AACA,YAAQ,OAAO,OAAO,aAAa,aAAa,MAAM,UAAU,CAAC;AAEjE,QAAI,QAAQ;AACZ,QAAI,SAAS,OAAO;AAEpB,WAAO,UAAU,eACjB;AACI,mBAAa,QAAQ,MAAM;AAC3B,YAAM,OAAO,OAAO,MAAM;AAC1B,cAAQ,OAAO,KAAK,YAAY,QAAQ;AACxC,cAAQ,OAAO,KAAK,YAAY,OAAO,QAAQ;AAC/C,eAAS;AAET,UAAI,SAAS,OAAO,WACpB;AACI,gBAAQ,OAAO,UAAU,OAAO,QAAQ;AAAA,MAC5C;AAEA,eAAS,KAAK;AAAA,IAClB;AACA,YAAQ,OAAO,SAAS,OAAO,SAAS;AAAA,EAC5C;AAEA,MAAI,OAAO,eAAe,eAC1B;AACI,YAAQ,OAAO,OAAO,eAAe,aAAa;AAClD,YAAQ,OAAO,OAAO,eAAe,CAAC;AAEtC,QAAI,OAAO,eAAe,GAC1B;AACI,cAAQ,OAAO,OAAO,eAAe,OAAO,WAAW;AAAA,IAC3D;AACA,YAAQ,OAAO,OAAO,gBAAgB,aAAa,MAAM,aAAa,CAAC;AAEvE,QAAI,QAAQ;AACZ,QAAI,YAAY,OAAO;AAEvB,WAAO,aAAa,eACpB;AACI,mBAAa,MAAM,cAAc,SAAS;AAC1C,YAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,cAAQ,OAAO,QAAQ,YAAY,OAAO,QAAQ;AAClD,cAAQ,OAAO,QAAQ,YAAY,QAAQ;AAC3C,eAAS;AAET,UAAI,SAAS,OAAO,cACpB;AACI,gBAAQ,OAAO,aAAa,OAAO,WAAW;AAAA,MAClD;AAEA,kBAAY,QAAQ;AAAA,IACxB;AACA,YAAQ,OAAO,SAAS,OAAO,YAAY;AAAA,EAC/C,OAEA;AACI,YAAQ,OAAO,OAAO,eAAe,aAAa;AAClD,YAAQ,OAAO,OAAO,gBAAgB,CAAC;AAAA,EAC3C;AAEA,MAAI,OAAO,aAAa,eACxB;AACI,YAAQ,OAAO,OAAO,aAAa,aAAa;AAChD,YAAQ,OAAO,OAAO,aAAa,CAAC;AAEpC,QAAI,OAAO,aAAa,GACxB;AACI,cAAQ,OAAO,OAAO,aAAa,OAAO,SAAS;AAAA,IACvD;AACA,YAAQ,OAAO,OAAO,cAAc,aAAa,MAAM,WAAW,CAAC;AAEnE,QAAI,QAAQ;AACZ,QAAI,UAAU,OAAO;AAErB,WAAO,WAAW,eAClB;AACI,mBAAa,MAAM,YAAY,OAAO;AACtC,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,cAAQ,OAAO,MAAM,YAAY,OAAO,QAAQ;AAChD,eAAS;AAET,UAAI,SAAS,OAAO,YACpB;AACI,gBAAQ,OAAO,WAAW,OAAO,SAAS;AAAA,MAC9C;AAEA,gBAAU,MAAM;AAAA,IACpB;AACA,YAAQ,OAAO,SAAS,OAAO,UAAU;AAAA,EAC7C,OAEA;AACI,YAAQ,OAAO,OAAO,aAAa,aAAa;AAChD,YAAQ,OAAO,OAAO,cAAc,CAAC;AAAA,EACzC;AACJ;;;AC76BO,SAAS,YAAY,SAAS,KACrC;AACI,MAAI,GAAG,IAAI,QAAQ;AACnB,MAAI,GAAG,IAAI,QAAQ;AACnB,MAAI,GAAG,KAAK,QAAQ,MAAM;AAC1B,MAAI,GAAG,KAAK,QAAQ,SAAS;AAC7B,MAAI,GAAG,KAAK,QAAQ,UAAU,CAAC;AAC/B,MAAI,YAAY,KAAK,QAAQ,WAAW;AAExC,SAAO;AACX;AAEO,SAAS,UAAU,OAAO,QACjC;AACI,SAAO,MAAM,UAAU,MAAM;AACjC;AAEO,SAAS,gBAAgB,OAAO,QACvC;AACI,UAAQ,OAAO,eAAe,MAAM,GAAG,kBAAkB,KAAK,UAAU,MAAM,CAAC;AAAA,EAAK,IAAI,MAAM,EAAE,KAAK,EAAE;AAEvG,SAAO,UAAU,OAAO,OAAO,SAAS,CAAC;AAC7C;AAEO,SAAS,wBAAwB,OAAO,MAC/C;AACI,UAAQ,OAAO,KAAK,KAAK,YAAY,KAAK,WAAW,MAAM,eAAe,MAAM;AAChF,QAAM,MAAM,MAAM,eAAe,KAAK,QAAQ;AAC9C,UAAQ,OAAO,KAAK,KAAK,cAAc,KAAK,cAAc,IAAI,KAAK,KAAK;AACxE,QAAM,UAAU,IAAI,KAAK,KAAK,KAAK,UAAU;AAC7C,UAAQ,OAAO,QAAQ,aAAa,IAAI;AACxC,UAAQ,OAAO,QAAQ,UAAU,KAAK,IAAI;AAC1C,UAAQ,OAAO,CAAC,OAAO,MAAM,QAAQ,UAAU,EAAE,CAAC,CAAC;AACnD,UAAQ,OAAO,CAAC,OAAO,MAAM,QAAQ,UAAU,EAAE,CAAC,CAAC;AAEnD,SAAO,QAAQ;AACnB;AAEO,SAAS,mBAAmB,OAAO,QAC1C;AAEI,QAAM,OAAO,MAAM,UAAU,MAAM;AAEnC,SAAO,wBAAwB,OAAO,IAAI;AAC9C;AAEO,SAAS,aAAa,OAAO,QACpC;AAEI,QAAM,OAAO,MAAM,UAAU,MAAM;AAEnC,SAAO,IAAI,SAAS,SAAS,GAAG,MAAM,SAAS,KAAK,QAAQ;AAChE;AAEO,SAAS,aAAa,OAAO,MACpC;AAEI,UAAQ,OAAO,KAAK,YAAY,CAAC;AACjC,QAAM,MAAM,MAAM,eAAe,KAAK,QAAQ;AAC9C,UAAQ,OAAO,KAAK,KAAK,cAAc,KAAK,aAAa,IAAI,KAAK,KAAK;AAEvE,SAAO,IAAI,KAAK,KAAK,KAAK,UAAU;AACxC;AAEO,SAAS,eAAe,OAAO,MACtC;AAEI,UAAQ,OAAO,KAAK,YAAY,CAAC;AAEjC,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AAGtD,WAAO,IAAI,OAAO,KAAK,KAAK,UAAU;AAAA,EAC1C;AAEA,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO,UAAU,MACvD;AACI,UAAQ,OAAO,KAAK,aAAa,aAAa;AAC9C,UAAQ,OAAO,KAAK,eAAe,aAAa;AAChD,UAAQ,OAAO,KAAK,eAAe,aAAa;AAChD,UAAQ,OAAO,aAAa,UAAU,cAAc;AAEpD,QAAM,SAAS,eAAe,OAAO,QAAQ;AAE7C,OAAK,WAAW,OAAO;AACvB,SAAO,WAAW,KAAK;AACvB,SAAO,WAAW,KAAK;AACvB,SAAO,YAAY;AACvB;AAEO,SAAS,uBAAuB,OAAO,MAC9C;AACI,MAAI,KAAK,aAAa,eACtB;AAGI;AAAA,EACJ;AAEA,QAAM,WAAW,KAAK;AAGtB,QAAM,SAAS,MAAM,YAAY,QAAQ;AAGzC,MAAI,KAAK,eAAe,eACxB;AACI,UAAM,WAAW,UAAU,OAAO,KAAK,UAAU;AACjD,aAAS,aAAa,KAAK;AAAA,EAC/B;AAEA,MAAI,KAAK,eAAe,eACxB;AACI,UAAM,WAAW,UAAU,OAAO,KAAK,UAAU;AACjD,aAAS,aAAa,KAAK;AAAA,EAC/B;AAEA,UAAQ,OAAO,OAAO,YAAY,CAAC;AACnC,SAAO,aAAa;AACpB,MAAI,kBAAkB;AAEtB,MAAI,OAAO,aAAa,KAAK,IAC7B;AACI,WAAO,WAAW,KAAK;AAEvB,QAAI,OAAO,aAAa,eACxB;AAEI,cAAQ,OAAO,OAAO,aAAa,KAAK,EAAE;AAC1C,cAAQ,OAAO,OAAO,cAAc,CAAC;AACrC,cAAQ,OAAO,OAAO,iBAAiB,CAAC;AACxC,cAAQ,OAAO,OAAO,eAAe,CAAC;AAGtC,sBAAgB,OAAO,OAAO,QAAQ;AACtC,wBAAkB;AAAA,IACtB;AAAA,EACJ,WACS,OAAO,aAAa,KAAK,IAClC;AACI,WAAO,WAAW,KAAK;AAAA,EAC3B;AAEA,MAAI,oBAAoB,OACxB;AACI,qBAAiB,OAAO,QAAQ;AAAA,EACpC;AAEA,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,OAAK,aAAa;AACtB;AAEO,SAAS,sBAAsB,OAAO,MAAM,YACnD;AAEI,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,YAAY,WAAW;AAC7B,UAAM,YAAY,UAAU;AAE5B,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,cAAU,QAAQ,MAAM,SAAS,EAAE;AACnC,qBAAiB,OAAO,SAAS,UAAU;AAAA,EAC/C;AAEA,uBAAqB,KAAK;AAC9B;AAsBO,SAAS,aAAa,SAAS,KACtC;AAEI,UAAQ,OAAO,eAAe,IAAI,QAAQ,CAAC;AAC3C,UAAQ,OAAO,cAAc,IAAI,QAAQ,CAAC;AAC1C,UAAQ,OAAO,eAAe,IAAI,cAAc,CAAC;AACjD,UAAQ,OAAO,UAAU,IAAI,eAAe,CAAC;AAC7C,UAAQ,OAAO,UAAU,IAAI,aAAa,KAAK,IAAI,iBAAiB,CAAG;AACvE,UAAQ,OAAO,UAAU,IAAI,cAAc,KAAK,IAAI,kBAAkB,CAAG;AACzE,UAAQ,OAAO,UAAU,IAAI,cAAc,KAAK,IAAI,kBAAkB,CAAG;AACzE,UAAQ,OAAO,UAAU,IAAI,YAAY,CAAC;AAE1C,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,MAAI,MAAM,QACV;AACI,YAAQ,KAAK,4FAA4F;AAEzG,WAAO,IAAI,SAAS,GAAG,GAAG,CAAC;AAAA,EAC/B;AAEA,QAAM,WAAW,IAAI,WAAW,IAAI,gBAAgB,UAAU,IAAI;AAGlE,MAAI;AAEJ,MAAI,IAAI,cAAc,OACtB;AAEI,YAAQ,UAAU;AAAA,EACtB,WACS,IAAI,SAAS,WAAW,eACjC;AACI,YAAQ,UAAU;AAAA,EACtB,WACS,YAAY,MACrB;AACI,YAAQ,UAAU;AAAA,EACtB,OAEA;AAEI,YAAQ,UAAU,MAAM,eAAe;AACvC,YAAQ,KAAK,iCAAiC,KAAK;AAEnD,QAAI,UAAU,MAAM,eAAe,QACnC;AACI,YAAMC,OAAM,IAAI,YAAY;AAC5B,MAAAA,KAAI,WAAW;AACf,YAAM,eAAe,KAAKA,IAAG;AAAA,IACjC,OAEA;AACI,cAAQ,OAAO,MAAM,eAAe,KAAK,EAAE,aAAa,aAAa;AAAA,IACzE;AAEA,UAAM,eAAe,KAAK,EAAE,WAAW;AAAA,EAC3C;AAIA,QAAM,SAAS,UAAU,MAAM,UAAU;AAEzC,QAAM,MAAM,MAAM,eAAe,KAAK;AACtC,QAAM,UAAU,aAAa,IAAI,IAAI;AAErC,SAAO,OAAO,SAAS;AAAA,IACnB,WAAW,IAAI,YAAY,IAAI,UAAU,IAAI,QAAQ;AAAA,IACrD,QAAQ,IAAI,SAAS,MAAM;AAAA,IAC3B,WAAW,IAAI;AAAA,IACf,UAAU,IAAI,SAAS;AAAA,IACvB,UAAU,IAAI,SAAS;AAAA,IACvB,aAAa,IAAI,OAAO;AAAA,IACxB,OAAO,IAAI,OAAO;AAAA,IAClB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW;AAAA,IACX,eAAe,IAAI;AAAA,IACnB,gBAAgB,IAAI;AAAA,IACpB,cAAc,IAAI;AAAA,IAClB;AAAA,IACA,UAAU,IAAI;AAAA,IACd,mBAAmB,IAAI;AAAA,IACvB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,eAAe;AAAA,EACnB,CAAC;AACD,UAAQ,OAAO,QAAQ,SAAS;AAEhC,MAAI,UAAU,UAAU,aACxB;AACI,UAAM,YAAY,eAAe,IAAI,MAAM;AAC3C,YAAQ,QAAQ,YAAY,QAAU,CAAC;AAEvC,WAAO,OAAO,WAAW;AAAA,MACrB,gBAAgB,IAAI;AAAA,MACpB,iBAAiB,IAAI;AAAA,MACrB,eAAe,IAAI,MAAM;AAAA,IAC7B,CAAC;AAAA,EACL;AAGA,SAAO,UAAU,MAAM,UAAU,QACjC;AACI,UAAM,UAAU,KAAK,IAAI,OAAO,CAAC;AAAA,EACrC;AAEA,UAAQ,OAAO,MAAM,UAAU,MAAM,EAAE,OAAO,eAAe,YAAY,SAAS,SAAS,MAAM,UAAU,MAAM,EAAE,EAAE;AAGrH,QAAM,OAAO,MAAM,UAAU,MAAM;AACnC,SAAO,OAAO,MAAM;AAAA,IAChB,UAAU,IAAI;AAAA,IACd,UAAU;AAAA,IACV,YAAY,IAAI,KAAK,QAAQ;AAAA,IAC7B,UAAU,KAAK,WAAW;AAAA,IAC1B,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,cAAc;AAAA;AAAA,IACd,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,IAAI;AAAA;AAAA,IACJ,gBAAgB,IAAI;AAAA,IACpB,WAAW;AAAA,IACX,MAAM,IAAI;AAAA,IACV,aAAa,IAAI;AAAA,IACjB,eAAe,IAAI;AAAA,IACnB,eAAe;AAAA,IACf,UAAU;AAAA,IACV,gBAAgB,IAAI;AAAA,EACxB,CAAC;AAGD,MAAI,SAAS,UAAU,aACvB;AACI,0BAAsB,OAAO,OAAO,IAAI;AAAA,EAC5C;AAEA,uBAAqB,KAAK;AAE1B,SAAO,IAAI,SAAS,SAAS,GAAG,MAAM,SAAS,KAAK,QAAQ;AAChE;AAOO,SAAS,WAAW,OAAO,MAClC;AACI,MAAI,KAAK,YAAY,UAAU,qBAC/B;AACI,oBAAgB,OAAO,KAAK,QAAQ;AAEpC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAkBO,SAAS,cAAc,QAC9B;AAEI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAG1C,QAAM,aAAa;AAGnB,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,UAAU,WAAW;AAC3B,UAAM,YAAY,UAAU;AAE5B,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,cAAU,MAAM,MAAM,SAAS,EAAE;AAGjC,2BAAuB,OAAO,OAAO,UAAU;AAAA,EACnD;AAGA,wBAAsB,OAAO,MAAM,UAAU;AAG7C,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,wBAAoB,OAAO,MAAM,UAAU;AAG3C,aAAS,MAAM,aAAa,OAAO;AACnC,UAAM,KAAK;AAEX,cAAU,MAAM;AAAA,EACpB;AAGA,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,eAAe;AAGrB,aAAS,MAAM,aAAa,OAAO;AACnC,UAAM,KAAK;AAEX,cAAU,MAAM;AAAA,EACpB;AAEA,yBAAuB,OAAO,IAAI;AAIlC,UAAQ,OAAO,KAAK,YAAY,aAAa;AAC7C,QAAM,MAAM,MAAM,eAAe,KAAK,QAAQ;AAC9C,QAAM,aAAa,gBAAgB,IAAI,MAAM,KAAK,UAAU;AAE5D,MAAI,eAAe,eACnB;AAII,UAAM,WAAW,IAAI,KAAK,KAAK,KAAK,UAAU;AAE9C,UAAM,UAAU,SAAS;AACzB,UAAM,YAAY,MAAM,UAAU,OAAO;AACzC,YAAQ,OAAO,UAAU,eAAe,UAAU;AAClD,cAAU,aAAa,KAAK;AAAA,EAChC;AAGA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,SAAS,kBAAkB,IAAI,QAAQ,KAAK,UAAU;AAG5D,YAAQ,OAAO,WAAW,UAAU;AAAA,EACxC,WACU,IAAI,YAAY,UAAU,uBAAuB,IAAI,KAAK,SAAS,GAC7E;AAEI,uBAAoB,OAAO,IAAI,QAAS;AAAA,EAC5C;AAGA,WAAS,MAAM,YAAY,KAAK,EAAE;AAElC,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,OAAK,KAAK;AAEV,uBAAqB,KAAK;AAC9B;AAWO,SAAS,0BAA0B,QAC1C;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAG1C,SAAO,KAAK;AAChB;AAcO,SAAS,sBAAsB,QAAQ,aAAa,UAC3D;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,aAAa,KAAK;AACtB,MAAI,QAAQ;AAEZ,SAAO,eAAe,iBAAiB,QAAQ,UAC/C;AACI,UAAM,YAAY,cAAc;AAChC,UAAM,YAAY,aAAa;AAG/B,UAAM,UAAU,MAAM,aAAa,SAAS;AAG5C,QAAI,QAAQ,QAAQ,eAAe,wBACnC;AACI,YAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAChD,YAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAEhD,kBAAY,KAAK,EAAE,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,OAAO,QAAQ,OAAO,QAAQ;AACzF,kBAAY,KAAK,EAAE,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,OAAO,QAAQ,OAAO,QAAQ;AAEzF,YAAM,aAAa,gBAAgB,OAAO,OAAO;AACjD,kBAAY,KAAK,EAAE,WAAW,WAAW;AAEzC,eAAS;AAAA,IACb;AAEA,iBAAa,QAAQ,MAAM,SAAS,EAAE;AAAA,EAC1C;AAEA,UAAQ,OAAO,SAAS,QAAQ;AAEhC,SAAO;AACX;AAWO,SAAS,mBAAmB,QACnC;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI,WAAO,IAAI,OAAO;AAAA,EACtB;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,gBAAgB,eACzB;AACI,UAAM,YAAY,mBAAmB,OAAO,KAAK,EAAE;AACnD,UAAMC,QAAO,IAAI,OAAO,UAAU,EAAE,GAAG,UAAU,EAAE,GAAG,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;AAElF,WAAOA;AAAA,EACX;AAEA,MAAI,QAAQ,MAAM,WAAW,KAAK,WAAW;AAC7C,MAAI,OAAO,MAAM;AAEjB,SAAO,MAAM,gBAAgB,eAC7B;AACI,YAAQ,MAAM,WAAW,MAAM,WAAW;AAC1C,WAAO,aAAa,MAAM,MAAM,IAAI;AAAA,EACxC;AAEA,SAAO;AACX;AAEO,SAAS,qBAAqB,OAAO,MAC5C;AACI,QAAM,UAAU,aAAa,OAAO,IAAI;AAGxC,UAAQ,OAAO;AACf,UAAQ,UAAU;AAClB,UAAQ,UAAU;AAClB,UAAQ,aAAa;AAGrB,UAAQ,YAAY;AACpB,UAAQ,YAAY;AAGpB,MAAI,KAAK,SAAS,WAAW,gBAC7B;AACI,YAAQ,SAAS,QAAQ,UAAU,EAAE,MAAM;AAG3C,QAAI,KAAK,SAAS,WAAW,kBAC7B;AACI,UAAIC,WAAU,KAAK;AAEnB,aAAOA,aAAY,eACnB;AACI,cAAM,IAAI,MAAM,WAAWA,QAAO;AAClC,QAAAA,WAAU,EAAE;AAEZ,cAAM,SAAS,qBAAqB,GAAG,IAAI,OAAO,CAAC;AACnD,gBAAQ,YAAY,KAAK,IAAI,QAAQ,WAAW,OAAO,SAAS;AAChE,gBAAQ,YAAY,KAAK,IAAI,QAAQ,WAAW,OAAO,SAAS;AAAA,MACpE;AAAA,IACJ;AAEA;AAAA,EACJ;AAGA,MAAI,cAAc,IAAI,OAAO;AAC7B,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,IAAI,MAAM,WAAW,OAAO;AAClC,cAAU,EAAE;AAEZ,QAAI,EAAE,YAAY,GAClB;AACI;AAAA,IACJ;AAEA,UAAM,WAAW,mBAAmB,CAAC;AACrC,YAAQ,QAAQ,SAAS;AACzB,kBAAc,SAAS,aAAa,SAAS,MAAM,SAAS,MAAM;AAClE,YAAQ,WAAW,SAAS;AAAA,EAChC;AAGA,UAAQ,OAAO,QAAQ,OAAO,GAAK,oDAAoD;AAEvF,MAAI,QAAQ,OAAO,GACnB;AACI,YAAQ,UAAU,IAAM,QAAQ;AAChC,kBAAc,QAAQ,QAAQ,SAAS,WAAW;AAAA,EACtD;AAEA,MAAI,QAAQ,UAAU,KAAO,KAAK,kBAAkB,OACpD;AAEI,YAAQ,WAAW,QAAQ,OAAO,MAAM,aAAa,WAAW;AAChE,YAAQ,OAAO,QAAQ,UAAU,CAAG;AACpC,YAAQ,aAAa,IAAM,QAAQ;AAAA,EACvC,OAEA;AACI,YAAQ,UAAU;AAClB,YAAQ,aAAa;AAAA,EACzB;AAGA,QAAM,YAAY,QAAQ,OAAO,MAAM;AACvC,UAAQ,cAAc;AACtB,UAAQ,SAAS,iBAAiB,QAAQ,WAAW,QAAQ,WAAW;AAGxE,QAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,MAAI,UAAU,MACd;AACI,UAAM,cAAc,UAAU,MAAM,iBAAiB,MAAM,QAAQ,QAAQ,SAAS,CAAC;AACrF,UAAM,iBAAiB,MAAM,MAAM,gBAAgB,WAAW;AAAA,EAClE;AAGA,YAAU,KAAK;AAEf,SAAO,YAAY,eACnB;AACI,UAAM,IAAI,MAAM,WAAW,OAAO;AAClC,cAAU,EAAE;AAEZ,UAAM,SAAS,qBAAqB,GAAG,WAAW;AAClD,YAAQ,YAAY,KAAK,IAAI,QAAQ,WAAW,OAAO,SAAS;AAChE,YAAQ,YAAY,KAAK,IAAI,QAAQ,WAAW,OAAO,SAAS;AAAA,EACpE;AACJ;AAWO,SAAS,mBAAmB,QACnC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,UAAU;AACrB;AAWO,SAAS,mBAAmB,QACnC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,UAAU;AACrB;AAcO,SAAS,oBAAoB,QACpC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,wBAAwB,OAAO,IAAI;AAC9C;AAYO,SAAS,qBAAqB,QAAQ,YAC7C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,oBAAoB,WAAW,UAAU;AACpD;AAYO,SAAS,qBAAqB,QAAQ,YAC7C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,iBAAiB,WAAW,UAAU;AACjD;AAYO,SAAS,sBAAsB,QAAQ,aAC9C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,kBAAkB,UAAU,GAAG,WAAW;AACrD;AAaO,SAAS,sBAAsB,QAAQ,aAC9C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,SAAO,eAAe,UAAU,GAAG,WAAW;AAClD;AAiBO,SAAS,oBAAoB,QAAQ,UAAU,UACtD;AACI,UAAQ,OAAO,eAAe,QAAQ,CAAC;AACvC,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,UAAQ,OAAO,cAAc,QAAQ,KAAK,cAAc,QAAQ,UAAU,CAAC,CAAC;AAE5E,UAAQ,UAAU,IAAI;AAEtB,MAAI,aAAa,QACjB;AACI,YAAQ,UAAU,IAAI;AAAA,EAC1B;AACA,UAAQ,SAAS,iBAAiB,QAAQ,WAAW,QAAQ,WAAW;AAExE,UAAQ,YAAY,QAAQ,UAAU;AACtC,UAAQ,WAAW,QAAQ,OAAO;AAClC,UAAQ,WAAW,QAAQ,OAAO;AAElC,QAAM,aAAa,MAAM;AAEzB,QAAM,YAAY,QAAQ;AAC1B,QAAM,SAAS;AACf,QAAM,sBAAsB;AAE5B,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,OAAO,mBAAmB,OAAO,SAAS;AAChD,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,UAAM,OAAO;AAEb,QAAI,gBAAgB,MAAM,SAAS,IAAI,MAAM,OAC7C;AACI,YAAM,UAAU,IAAI;AAAA,QAAO,KAAK,cAAc;AAAA,QAAQ,KAAK,cAAc;AAAA,QACrE,KAAK,cAAc;AAAA,QAAQ,KAAK,cAAc;AAAA,MAAM;AACxD,YAAM,UAAU;AAGhB,UAAI,MAAM,aAAa,eACvB;AACI,+BAAuB,YAAY,MAAM,UAAU,OAAO;AAAA,MAC9D;AAAA,IACJ;AAEA,cAAU,MAAM;AAAA,EACpB;AACJ;AAYO,SAAS,yBAAyB,QACzC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,MAAI,UAAU,MACd;AACI,WAAO,MAAM,eAAe,MAAM;AAAA,EACtC;AAEA,SAAO,IAAI,OAAO;AACtB;AAWO,SAAS,0BAA0B,QAC1C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,MAAI,UAAU,MACd;AACI,WAAO,MAAM;AAAA,EACjB;AAEA,SAAO;AACX;AAaO,SAAS,yBAAyB,QAAQ,gBACjD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,QAAQ,WAAW,eAC5B;AACI;AAAA,EACJ;AAEA,MAAI,gBAAgB,cAAc,IAAI,GACtC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,QAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,iBAAiB;AAC3B;AAaO,SAAS,0BAA0B,QAAQ,iBAClD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,QAAQ,WAAW,iBAAiB,KAAK,eAClD;AACI;AAAA,EACJ;AAEA,MAAI,oBAAoB,GACxB;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,QAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,kBAAkB;AAC5B;AAeO,SAAS,kBAAkB,QAAQ,OAAO,OAAO,MACxD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,UAAU,aAAa,OAAO,IAAI;AACxC,YAAQ,QAAQ,MAAM,QAAQ,OAAO,KAAK;AAC1C,YAAQ,UAAU,QAAQ,MAAM,OAAO,QAAQ,MAAM,GAAG,KAAK;AAAA,EACjE;AACJ;AAYO,SAAS,0BAA0B,QAAQ,OAAO,MACzD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,UAAU,aAAa,OAAO,IAAI;AACxC,YAAQ,QAAQ,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC9C;AACJ;AAcO,SAAS,mBAAmB,QAAQ,QAAQ,MACnD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,UAAU,aAAa,OAAO,IAAI;AACxC,YAAQ,UAAU;AAAA,EACtB;AACJ;AAcO,SAAS,0BAA0B,QAAQ,SAAS,OAAO,MAClE;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,aAAa,KAAK;AACxB,UAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AACtD,YAAQ,OAAO,KAAK,cAAc,aAAa,IAAI,OAAO,KAAK;AAC/D,UAAM,QAAQ,IAAI,OAAO,KAAK,UAAU;AACxC,UAAM,UAAU,IAAI,KAAK,KAAK,UAAU;AACxC,UAAM,iBAAiB,SAAS,MAAM,gBAAgB,QAAQ,SAAS,OAAO;AAC9E,UAAM,mBAAmB,QAAQ,aAAa,QAAQ,MAAM,OAAO,QAAQ,MAAM,GAAG,OAAO;AAAA,EAC/F;AACJ;AAcO,SAAS,kCAAkC,QAAQ,SAAS,MACnE;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,aAAa,KAAK;AACxB,UAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AACtD,YAAQ,OAAO,KAAK,cAAc,aAAa,IAAI,OAAO,KAAK;AAC/D,UAAM,QAAQ,IAAI,OAAO,KAAK,UAAU;AACxC,UAAM,UAAU,IAAI,KAAK,KAAK,UAAU;AACxC,UAAM,iBAAiB,SAAS,MAAM,gBAAgB,QAAQ,SAAS,OAAO;AAAA,EAClF;AACJ;AAcO,SAAS,2BAA2B,QAAQ,SAAS,MAC5D;AACI,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,QAAM,QAAQ,WAAW,OAAO,MAAM;AAEtC,QAAM,KAAK,OAAO,SAAS;AAG3B,QAAM,OAAO,MAAM,UAAU,EAAE;AAC/B,UAAQ,OAAO,KAAK,aAAa,OAAO,QAAQ;AAEhD,MAAI,QAAQ,KAAK,YAAY,UAAU,qBACvC;AAEI,eAAW,OAAO,IAAI;AAAA,EAC1B;AAEA,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,UAAM,aAAa,KAAK;AACxB,UAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AACtD,YAAQ,OAAO,KAAK,cAAc,aAAa,IAAI,OAAO,KAAK;AAC/D,UAAM,QAAQ,IAAI,OAAO,KAAK,UAAU;AACxC,UAAM,MAAM,IAAI,KAAK,KAAK,UAAU;AACpC,UAAM,mBAAmB,IAAI,aAAa;AAAA,EAC9C;AACJ;AAWO,SAAS,eAAe,QAC/B;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AA0BO,SAAS,eAAe,QAAQ,MACvC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,QAAM,eAAe,KAAK;AAE1B,MAAI,iBAAiB,MACrB;AACI;AAAA,EACJ;AAEA,MAAI,KAAK,aAAa,UAAU,gBAChC;AAEI,SAAK,OAAO;AAGZ,yBAAqB,OAAO,IAAI;AAEhC;AAAA,EACJ;AAGA,QAAM,aAAa;AACnB,wBAAsB,OAAO,MAAM,UAAU;AAG7C,aAAW,OAAO,IAAI;AAGtB;AACI,QAAI,WAAW,KAAK;AAEpB,WAAO,aAAa,eACpB;AACI,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,WAAW;AAE7B,YAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,UAAI,MAAM,aAAa,eACvB;AACI,sBAAc,OAAO,KAAK;AAAA,MAC9B;AAKA,YAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AACnD,YAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AACnD,iBAAW,OAAO,KAAK;AACvB,iBAAW,OAAO,KAAK;AAEvB,iBAAW,MAAM,MAAM,SAAS,EAAE;AAAA,IACtC;AAAA,EACJ;AAEA,OAAK,OAAO;AAEZ,MAAI,iBAAiB,WAAW,YAChC;AAEI,YAAQ,OAAO,KAAK,aAAa,UAAU,YAAY;AAEvD,UAAM,YAAY,MAAM,eAAe,UAAU,YAAY;AAC7D,UAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAG3D,mBAAe,OAAO,UAAU,WAAW,IAAI;AAG/C,0BAAsB,OAAO,UAAU,aAAa,IAAI;AAGxD,QAAI,WAAW,KAAK;AAEpB,WAAO,aAAa,eACpB;AACI,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,WAAW;AAE7B,YAAM,QAAQ,MAAM,WAAW,OAAO;AAGtC,UAAI,MAAM,aAAa,UAAU,cACjC;AACI,wBAAgB,OAAO,UAAU,WAAW,KAAK;AAAA,MACrD,WACS,MAAM,aAAa,UAAU,aACtC;AAKI,wBAAgB,OAAO,WAAW,UAAU,KAAK;AAGjD,wBAAgB,OAAO,UAAU,WAAW,KAAK;AAAA,MACrD,OAEA;AAEI,gBAAQ,OAAO,MAAM,aAAa,UAAU,cAAc;AAAA,MAC9D;AAEA,iBAAW,MAAM,MAAM,SAAS,EAAE;AAAA,IACtC;AAGA,UAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAI,UAAU,KAAK;AAEnB,WAAO,YAAY,eACnB;AACI,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,gBAAU,MAAM;AAChB,0BAAoB,OAAO,MAAM,UAAU;AAC3C,YAAM,oBAAoB;AAC1B,YAAM,YAAY;AAClB,yBAAmB,OAAO,MAAM,YAAY,WAAW,WAAW,iBAAiB;AAAA,IACvF;AAAA,EACJ,WAGS,SAAS,WAAW,eAC7B;AAEI,YAAQ,OAAO,KAAK,aAAa,UAAU,WAAW;AAEtD,UAAM,YAAY,MAAM,eAAe,UAAU,YAAY;AAC7D,UAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAG3D,mBAAe,OAAO,WAAW,UAAU,IAAI;AAG/C,2BAAuB,OAAO,IAAI;AAGlC,QAAI,WAAW,KAAK;AAEpB,WAAO,aAAa,eACpB;AACI,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,WAAW;AAE7B,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,iBAAW,MAAM,MAAM,SAAS,EAAE;AAElC,YAAM,iBAAiB,YAAY;AACnC,YAAM,YAAY,MAAM,UAAU,MAAM,MAAM,cAAc,EAAE,MAAM;AAGpE,UAAI,MAAM,aAAa,UAAU,gBACjC;AAEI,gBAAQ,OAAO,UAAU,aAAa,UAAU,cAAc;AAE9D;AAAA,MACJ;AAGA,cAAQ,OAAO,MAAM,aAAa,UAAU,WAAW;AAGvD,UAAI,UAAU,aAAa,UAAU,cACrC;AACI,wBAAgB,OAAO,WAAW,UAAU,KAAK;AAAA,MACrD,OAEA;AAEI,gBAAQ,OAAO,UAAU,aAAa,UAAU,WAAW;AAG3D,gBAAQ,OAAO,KAAK,MAAM,cAAc,MAAM,aAAa,kBAAkB;AAM7E,wBAAgB,OAAO,WAAW,UAAU,KAAK;AAGjD,wBAAgB,OAAO,UAAU,WAAW,KAAK;AAAA,MACrD;AAAA,IACJ;AAGA,UAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAI,UAAU,KAAK;AAEnB,WAAO,YAAY,eACnB;AACI,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,gBAAU,MAAM;AAChB,0BAAoB,OAAO,MAAM,UAAU;AAC3C,YAAM,oBAAoB;AAC1B,yBAAmB,OAAO,MAAM,YAAY,WAAW,eAAe,WAAW,iBAAiB;AAAA,IACtG;AAAA,EACJ,OAEA;AACI,YAAQ,OAAO,iBAAiB,WAAW,kBAAkB,iBAAiB,WAAW,gBAAgB;AAGzG,YAAQ,OAAO,SAAS,WAAW,kBAAkB,SAAS,WAAW,gBAAgB;AAGzF,UAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAI,UAAU,KAAK;AAEnB,WAAO,YAAY,eACnB;AACI,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,gBAAU,MAAM;AAChB,0BAAoB,OAAO,MAAM,UAAU;AAC3C,YAAM,YAAY;AAClB,YAAM,oBAAoB;AAC1B,yBAAmB,OAAO,MAAM,YAAY,WAAW,WAAW,iBAAiB;AAAA,IACvF;AAAA,EACJ;AAGA;AACI,QAAI,WAAW,KAAK;AAEpB,WAAO,aAAa,eACpB;AACI,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,WAAW;AAE7B,YAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,iBAAW,MAAM,MAAM,SAAS,EAAE;AAElC,YAAM,iBAAiB,YAAY;AACnC,YAAM,cAAc,MAAM,MAAM,cAAc,EAAE;AAGhD,YAAM,YAAY,MAAM,UAAU,WAAW;AAE7C,UAAI,UAAU,aAAa,UAAU,gBACrC;AACI;AAAA,MACJ;AAEA,UAAI,KAAK,SAAS,WAAW,iBAAiB,UAAU,SAAS,WAAW,eAC5E;AACI;AAAA,MACJ;AAEA,kBAAY,OAAO,KAAK;AAAA,IAC5B;AAAA,EACJ;AAGA,uBAAqB,OAAO,IAAI;AAEhC,yBAAuB,KAAK;AAC5B,uBAAqB,KAAK;AAC9B;AAaO,SAAS,mBAAmB,QAAQ,UAC3C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,OAAK,WAAW;AACpB;AAYO,SAAS,mBAAmB,QACnC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAWO,SAAS,eAAe,QAC/B;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAWO,SAAS,wBAAwB,QACxC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAWO,SAAS,4BAA4B,QAC5C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ,YAAY,MAAM;AACrC;AAYO,SAAS,4BAA4B,QAC5C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ,OAAO,MAAM;AAChC;AAgBO,SAAS,mBAAmB,QAAQ,UAC3C;AACI,UAAQ,OAAO,UAAU,SAAS,IAAI,KAAK,SAAS,QAAQ,CAAG;AAC/D,UAAQ,OAAO,UAAU,SAAS,iBAAiB,KAAK,SAAS,qBAAqB,CAAG;AACzF,UAAQ,OAAO,eAAe,SAAS,MAAM,CAAC;AAE9C,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,UAAQ,OAAO,SAAS;AACxB,UAAQ,UAAU,SAAS;AAC3B,UAAQ,cAAc,SAAS;AAE/B,QAAM,SAAS,iBAAiB,QAAQ,WAAW,SAAS,MAAM;AAClE,UAAQ,SAAS;AACjB,UAAQ,WAAW,OAAO;AAC1B,UAAQ,WAAW,OAAO;AAE1B,UAAQ,UAAU,QAAQ,OAAO,IAAM,IAAM,QAAQ,OAAO;AAC5D,UAAQ,aAAa,QAAQ,UAAU,IAAM,IAAM,QAAQ,UAAU;AACzE;AAaO,SAAS,mBAAmB,QACnC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AACxC,QAAM,WAAW,IAAI,WAAW;AAChC,WAAS,OAAO,QAAQ;AACxB,WAAS,SAAS,QAAQ;AAC1B,WAAS,oBAAoB,QAAQ;AAErC,SAAO;AACX;AAYO,SAAS,2BAA2B,QAC3C;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,uBAAqB,OAAO,IAAI;AACpC;AAaO,SAAS,wBAAwB,QAAQ,eAChD;AACI,UAAQ,OAAO,UAAU,aAAa,KAAK,iBAAiB,CAAG;AAE/D,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AACxC,UAAQ,gBAAgB;AAC5B;AAYO,SAAS,wBAAwB,QACxC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAaO,SAAS,yBAAyB,QAAQ,gBACjD;AACI,UAAQ,OAAO,UAAU,cAAc,KAAK,kBAAkB,CAAG;AAEjE,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AACxC,UAAQ,iBAAiB;AAC7B;AAWO,SAAS,yBAAyB,QACzC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAcO,SAAS,uBAAuB,QAAQ,cAC/C;AACI,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,UAAQ,OAAO,UAAU,YAAY,CAAC;AAEtC,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AACxC,UAAQ,eAAe;AAC3B;AASO,SAAS,uBAAuB,QACvC;AACI,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAYO,SAAS,eAAe,QAC/B;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK,aAAa,UAAU;AACvC;AAaO,SAAS,gBAAgB,QAAQ,OACxC;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,SAAS,KAAK,YAAY,UAAU,qBACxC;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B,WACS,UAAU,SAAS,KAAK,aAAa,UAAU,aACxD;AAEI,UAAM,SAAS,MAAM,YAAY,KAAK,QAAQ;AAE9C,QAAI,OAAO,wBAAwB,GACnC;AACI,oBAAc,OAAO,KAAK,QAAQ;AAAA,IACtC;AAEA,qBAAiB,OAAO,KAAK,QAAQ;AAAA,EACzC;AACJ;AAYO,SAAS,iBAAiB,QACjC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK,aAAa,UAAU;AACvC;AAWO,SAAS,sBAAsB,QACtC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAYO,SAAS,yBAAyB,QAAQ,eACjD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,OAAK,iBAAiB;AAC1B;AAWO,SAAS,yBAAyB,QACzC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAYO,SAAS,mBAAmB,QAAQ,aAC3C;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,OAAK,cAAc;AAEnB,MAAI,gBAAgB,OACpB;AACI,eAAW,OAAO,IAAI;AAAA,EAC1B;AACJ;AAeO,SAAS,eAAe,QAC/B;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,aAAa,UAAU,gBAChC;AACI;AAAA,EACJ;AAIA,QAAM,aAAa;AACnB,wBAAsB,OAAO,MAAM,UAAU;AAG7C,yBAAuB,OAAO,IAAI;AAGlC,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,cAAU,MAAM;AAChB,wBAAoB,OAAO,MAAM,UAAU;AAAA,EAC/C;AAIA,QAAM,MAAM,MAAM,eAAe,KAAK,QAAQ;AAC9C,QAAM,cAAc,MAAM,eAAe,UAAU,cAAc;AAGjE,iBAAe,OAAO,aAAa,KAAK,IAAI;AAG5C,MAAI,WAAW,KAAK;AAEpB,SAAO,aAAa,eACpB;AACI,UAAM,UAAU,YAAY;AAC5B,UAAM,YAAY,WAAW;AAE7B,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,eAAW,MAAM,MAAM,SAAS,EAAE;AAGlC,QAAI,MAAM,aAAa,UAAU,gBACjC;AACI;AAAA,IACJ;AAEA,YAAQ,OAAO,MAAM,aAAa,IAAI,YAAY,IAAI,aAAa,UAAU,YAAY;AAGzF,QAAI,MAAM,aAAa,eACvB;AACI,oBAAc,OAAO,KAAK;AAAA,IAC9B;AAIA,UAAM,WAAW,MAAM,eAAe,MAAM,QAAQ;AACpD,oBAAgB,OAAO,aAAa,UAAU,KAAK;AAAA,EACvD;AAEA,yBAAuB,KAAK;AAC5B,uBAAqB,KAAK;AAC9B;AAaO,SAAS,cAAc,QAC9B;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AAEA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,aAAa,UAAU,gBAChC;AACI;AAAA,EACJ;AAEA,QAAM,cAAc,MAAM,eAAe,UAAU,cAAc;AACjE,QAAM,QAAQ,KAAK,SAAS,WAAW,gBAAgB,UAAU,eAAe,UAAU;AAC1F,QAAM,YAAY,MAAM,eAAe,KAAK;AAE5C,iBAAe,OAAO,WAAW,aAAa,IAAI;AAElD,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAGrD,QAAM,YAAY,KAAK;AACvB,QAAM,oBAAoB;AAC1B,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,cAAU,MAAM;AAEhB,uBAAmB,OAAO,MAAM,YAAY,WAAW,WAAW,iBAAiB;AAAA,EACvF;AAEA,MAAI,UAAU,UAAU,cACxB;AACI,0BAAsB,OAAO,OAAO,IAAI;AAAA,EAC5C;AAIA,MAAI,WAAW,KAAK;AAEpB,SAAO,aAAa,eACpB;AACI,UAAM,UAAU,YAAY;AAC5B,UAAM,YAAY,WAAW;AAE7B,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,YAAQ,OAAO,MAAM,aAAa,UAAU,cAAc;AAC1D,YAAQ,OAAO,MAAM,aAAa,aAAa;AAE/C,eAAW,MAAM,MAAM,SAAS,EAAE;AAElC,UAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AACnD,UAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,MAAM;AAEnD,QAAI,MAAM,aAAa,UAAU,kBAAkB,MAAM,aAAa,UAAU,gBAChF;AAEI;AAAA,IACJ;AAGA,QAAI;AAEJ,QAAI,MAAM,aAAa,UAAU,gBAAgB,MAAM,aAAa,UAAU,cAC9E;AACI,mBAAa,UAAU;AAAA,IAC3B,WACS,MAAM,aAAa,UAAU,cACtC;AACI,mBAAa,MAAM;AAAA,IACvB,OAEA;AACI,mBAAa,MAAM;AAAA,IACvB;AAGA,UAAM,WAAW,MAAM,eAAe,UAAU;AAChD,oBAAgB,OAAO,UAAU,aAAa,KAAK;AAGnD,QAAI,eAAe,UAAU,cAC7B;AACI,kBAAY,OAAO,KAAK;AAAA,IAC5B;AAAA,EACJ;AAEA,yBAAuB,KAAK;AAC5B,uBAAqB,KAAK;AAC9B;AAaO,SAAS,wBAAwB,QAAQ,MAChD;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AACA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,MAAI,KAAK,kBAAkB,MAC3B;AACI,SAAK,gBAAgB;AACrB,UAAM,QAAQ,eAAe,OAAO,IAAI;AAExC,QAAI,UAAU,MACd;AACI,YAAM,kBAAkB;AAAA,IAC5B;AACA,yBAAqB,OAAO,IAAI;AAAA,EACpC;AACJ;AAUO,SAAS,uBAAuB,QACvC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAaO,SAAS,iBAAiB,QAAQ,MACzC;AACI,QAAM,QAAQ,iBAAiB,OAAO,MAAM;AAE5C,MAAI,UAAU,MACd;AACI;AAAA,EACJ;AACA,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AACxC,UAAQ,WAAW;AACvB;AAYO,SAAS,gBAAgB,QAChC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,QAAM,UAAU,aAAa,OAAO,IAAI;AAExC,SAAO,QAAQ;AACnB;AAUO,SAAS,uBAAuB,QAAQ,iBAC/C;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,MAAI,UAAU,KAAK;AAEnB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,kBAAkB;AACxB,cAAU,MAAM;AAAA,EACpB;AACJ;AAWO,SAAS,qBAAqB,QACrC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAcO,SAAS,iBAAiB,QAAQ,YACzC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,MAAI,UAAU,KAAK;AACnB,MAAI,aAAa;AAEjB,SAAO,YAAY,eACnB;AACI,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,KAAK,IAAI,UAAU,MAAM,KAAK,GAAG,OAAO,QAAQ,MAAM,QAAQ;AACpE,eAAW,UAAU,IAAI;AACzB,kBAAc;AACd,cAAU,MAAM;AAAA,EACpB;AAEA,SAAO;AACX;AAUO,SAAS,qBAAqB,QACrC;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAE1C,SAAO,KAAK;AAChB;AAcO,SAAS,iBAAiB,QAAQ,YAAY,UACrD;AACI,QAAM,QAAQ,WAAW,OAAO,MAAM;AACtC,QAAM,OAAO,gBAAgB,OAAO,MAAM;AAC1C,MAAI,WAAW,KAAK;AACpB,MAAI,aAAa;AAEjB,SAAO,aAAa,iBAAiB,aAAa,UAClD;AACI,UAAM,UAAU,YAAY;AAC5B,UAAM,YAAY,WAAW;AAC7B,UAAM,QAAQ,WAAW,OAAO,OAAO;AACvC,UAAM,KAAK,IAAI,UAAU;AACzB,OAAG,SAAS,UAAU;AACtB,OAAG,SAAS,OAAO;AACnB,OAAG,WAAW,MAAM;AACpB,eAAW,UAAU,IAAI;AACzB,kBAAc;AACd,eAAW,MAAM,MAAM,SAAS,EAAE;AAAA,EACtC;AAEA,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO,OAAO,OACpD;AACI,MAAI,MAAM,SAAS,WAAW,kBAAkB,MAAM,SAAS,WAAW,gBAC1E;AACI,WAAO;AAAA,EACX;AACA,MAAI;AACJ,MAAI;AAEJ,MAAI,MAAM,aAAa,MAAM,YAC7B;AACI,eAAW,MAAM;AACjB,kBAAc,MAAM;AAAA,EACxB,OAEA;AACI,eAAW,MAAM;AACjB,kBAAc,MAAM;AAAA,EACxB;AAEA,SAAO,aAAa,eACpB;AACI,UAAM,UAAU,YAAY;AAC5B,UAAM,YAAY,WAAW;AAC7B,UAAM,iBAAiB,YAAY;AACnC,UAAM,QAAQ,WAAW,OAAO,OAAO;AAEvC,QAAI,MAAM,qBAAqB,SAAS,MAAM,MAAM,cAAc,EAAE,WAAW,aAC/E;AACI,aAAO;AAAA,IACX;AACA,eAAW,MAAM,MAAM,SAAS,EAAE;AAAA,EACtC;AAEA,SAAO;AACX;AAGO,SAAS,gBAAgB,KAChC;AACI,QAAM,gBAAgB,CAAC,SACvB;AACI,QAAI,OAAO,SAAS,YAAY,SAAS,MACzC;AACI,aAAO,KAAK,IAAI,EAAE,QAAQ,SAC1B;AACI,gBAAQ,OAAO,KAAK,GAAG,GACvB;AAAA,UACI,KAAK;AACD,iBAAK,GAAG,IAAI;AAEZ;AAAA,UAEJ,KAAK;AACD,iBAAK,GAAG,IAAI;AAEZ;AAAA,UAEJ,KAAK;AACD,iBAAK,GAAG,IAAI;AAEZ;AAAA,UAEJ,KAAK;AACD,gBAAI,MAAM,QAAQ,KAAK,GAAG,CAAC,GAC3B;AAAA,YAEA,WACS,KAAK,GAAG,MAAM,MACvB;AACI,4BAAc,KAAK,GAAG,CAAC;AAAA,YAC3B,OAEA;AACI,mBAAK,GAAG,IAAI;AAAA,YAChB;AAEA;AAAA,QAGR;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAEA,gBAAc,GAAG;AACrB;;;ACx/EO,IAAM,SAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,KAAK;AACV,SAAK,OAAO,WAAW;AACvB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,iBAAiB;AAAA,EAC1B;AACJ;AAEO,IAAM,cAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,iBAAiB,IAAI,OAAO,GAAG,CAAC;AACrC,SAAK,kBAAkB;AACvB,SAAK,QAAQ;AACb,SAAK,gBAAgB,IAAI,OAAO,GAAG,CAAC;AACpC,SAAK,gBAAgB,IAAI,MAAM,GAAG,CAAC;AAAA,EACvC;AACJ;AAIO,IAAM,YAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,YAAY,IAAI,YAAY;AACjC,SAAK,SAAS,IAAI,OAAO,GAAG,CAAC;AAC7B,SAAK,YAAY,IAAI,MAAM,GAAG,CAAC;AAC/B,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,cAAc,IAAI,OAAO,GAAG,CAAC;AAClC,SAAK,QAAQ,IAAI,OAAO,GAAG,CAAC;AAC5B,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,OAAO,KACP;AACI,QAAI,YAAY,KAAK,UAAU,UAAU;AACzC,QAAI,SAAS,KAAK,OAAO,MAAM;AAC/B,QAAI,YAAY,KAAK,UAAU,MAAM;AACrC,QAAI,WAAW,KAAK;AACpB,QAAI,WAAW,KAAK;AACpB,QAAI,cAAc,KAAK,YAAY,MAAM;AACzC,QAAI,QAAQ,KAAK,MAAM,MAAM;AAC7B,QAAI,SAAS,KAAK;AAClB,QAAI,OAAO,KAAK;AAChB,QAAI,UAAU,KAAK;AACnB,QAAI,UAAU,KAAK;AACnB,QAAI,aAAa,KAAK;AACtB,QAAI,YAAY,KAAK;AACrB,QAAI,YAAY,KAAK;AACrB,QAAI,gBAAgB,KAAK;AACzB,QAAI,iBAAiB,KAAK;AAC1B,QAAI,eAAe,KAAK;AACxB,QAAI,SAAS,KAAK;AAClB,QAAI,SAAS,KAAK;AAClB,QAAI,WAAW,KAAK;AACpB,QAAI,gBAAgB,KAAK;AACzB,QAAI,oBAAoB,KAAK;AAC7B,QAAI,cAAc,KAAK;AAAA,EAC3B;AACJ;;;AC7FA,IAAM,sBAAsB;AAErB,IAAM,iBAAN,MACP;AAAA,EACI,YAAY,WAAW,GACvB;AACI,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,mBAAN,MACP;AAAA,EACI,YAAY,WAAW,GACvB;AACI,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,iBAAN,MACP;AAAA,EACI,YAAY,WAAW,GACvB;AACI,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,YAAY,WAAW,GACvB;AACI,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,eAAN,MACP;AAAA,EACI,YAAY,WAAW,GACvB;AACI,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,SAAS,qBAAqB,UACrC;AACI,QAAM,QAAQ,IAAI,eAAe,QAAQ;AAEzC,MAAI,WAAW,GACf;AACI,UAAM,OAAO,QAAQ,UAAU,MAAM;AAAE,aAAO,IAAI,UAAU;AAAA,IAAG,CAAC;AAEhE,WAAO;AAAA,EACX;AACA,QAAM,OAAO;AAEb,SAAO;AACX;AAiBO,SAAS,qBAAqB,UACrC;AACI,QAAM,QAAQ,IAAI,eAAe,QAAQ;AAEzC,MAAI,WAAW,GACf;AACI,UAAM,OAAO,QAAQ,UAAU,MAAM;AAAE,aAAO,IAAI,aAAa;AAAA,IAAG,CAAC;AAGnE,WAAO;AAAA,EACX;AACA,QAAM,OAAO;AAEb,SAAO;AACX;AAEO,SAAS,mBAAmB,UACnC;AACI,QAAM,QAAQ,IAAI,aAAa,QAAQ;AAEvC,MAAI,WAAW,GACf;AACI,UAAM,OAAO,QAAQ,UAAU,MAAM;AAAE,aAAO,IAAI,WAAW;AAAA,IAAG,CAAC;AAEjE,WAAO;AAAA,EACX;AACA,QAAM,OAAO;AAEb,SAAO;AACX;AAiBO,SAAS,aAAa,OAC7B;AACI,MAAI,MAAM,aAAa,GACvB;AACI,YAAQ,OAAO,MAAM,UAAU,CAAC;AAChC,UAAM,OAAO,QAAQ,qBAAqB,MAAM;AAAE,aAAO,IAAI,UAAU;AAAA,IAAG,CAAC;AAC3E,UAAM,WAAW;AACjB,UAAM,QAAQ;AAAA,EAClB,WACS,MAAM,UAAU,MAAM,UAC/B;AACI,UAAM,cAAc,IAAI,MAAM;AAC9B,WAAO,MAAM,MAAM,aAAa,MAAM;AAAE,aAAO,IAAI,UAAU;AAAA,IAAG,CAAC;AACjE,UAAM,WAAW;AAAA,EACrB,OAEA;AACI,oBAAgB,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,EAC3C;AAEA,QAAM,SAAS;AAEf,SAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,eAAe,OAC/B;AACI,MAAI,MAAM,aAAa,GACvB;AACI,YAAQ,OAAO,MAAM,UAAU,CAAC;AAChC,UAAM,OAAO,QAAQ,qBAAqB,MAAM;AAAE,aAAO,IAAI,YAAY;AAAA,IAAG,CAAC;AAC7E,UAAM,WAAW;AACjB,UAAM,QAAQ;AAAA,EAClB,WACS,MAAM,UAAU,MAAM,UAC/B;AACI,UAAM,cAAc,IAAI,MAAM;AAC9B,WAAO,MAAM,MAAM,aAAa,MAAM;AAAE,aAAO,IAAI,YAAY;AAAA,IAAG,CAAC;AACnE,UAAM,WAAW;AAAA,EACrB,OAEA;AACI,oBAAgB,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,EAC3C;AAEA,QAAM,SAAS;AAEf,SAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AACrC;AAGO,SAAS,aAAa,OAC7B;AACI,MAAI,MAAM,aAAa,GACvB;AACI,YAAQ,OAAO,MAAM,UAAU,CAAC;AAChC,UAAM,OAAO,QAAQ,qBAAqB,MAAM;AAAE,aAAO,IAAI,aAAa;AAAA,IAAG,CAAC;AAC9E,UAAM,WAAW;AACjB,UAAM,QAAQ;AAAA,EAClB,WACS,MAAM,UAAU,MAAM,UAC/B;AAEI,UAAM,cAAc,IAAI,MAAM;AAC9B,WAAO,MAAM,MAAM,aAAa,MAAM;AAAE,aAAO,IAAI,aAAa;AAAA,IAAG,CAAC;AACpE,UAAM,WAAW;AAAA,EACrB,OAEA;AACI,UAAM,MAAM,MAAM,KAAK,MAAM,KAAK;AAClC,oBAAgB,GAAG;AACnB,QAAI,WAAW,IAAI,WAAW;AAAA,EAClC;AAEA,QAAM,SAAS;AAEf,SAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,WAAW,OAC3B;AAEI,MAAI,MAAM,aAAa,GACvB;AACI,YAAQ,OAAO,MAAM,UAAU,CAAC;AAChC,UAAM,OAAO,QAAQ,qBAAqB,MAAM;AAAE,aAAO,IAAI,WAAW;AAAA,IAAG,CAAC;AAC5E,UAAM,WAAW;AACjB,UAAM,QAAQ;AAAA,EAClB,WACS,MAAM,UAAU,MAAM,UAC/B;AACI,UAAM,cAAc,IAAI,MAAM;AAC9B,WAAO,MAAM,MAAM,aAAa,MAAM;AAAE,aAAO,IAAI,WAAW;AAAA,IAAG,CAAC;AAClE,UAAM,WAAW;AAAA,EACrB,OAEA;AACI,oBAAgB,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,EAC3C;AAEA,QAAM,SAAS;AACf,UAAQ,OAAO,MAAM,KAAK,MAAM,QAAQ,CAAC,EAAE,SAAS,QAAW,GAAG,IAAI,MAAM,EAAE,KAAK,EAAE;AAErF,SAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,YAAY,OAC5B;AACI,MAAI,MAAM,aAAa,GACvB;AACI,YAAQ,OAAO,MAAM,UAAU,CAAC;AAChC,UAAM,OAAO,QAAQ,qBAAqB,MAAM;AAAE,aAAO,IAAI,YAAY;AAAA,IAAG,CAAC;AAC7E,UAAM,WAAW;AACjB,UAAM,QAAQ;AAAA,EAClB,WACS,MAAM,UAAU,MAAM,UAC/B;AACI,UAAM,cAAc,IAAI,MAAM;AAC9B,WAAO,MAAM,MAAM,aAAa,MAAM;AAAE,aAAO,IAAI,YAAY;AAAA,IAAG,CAAC;AACnE,UAAM,WAAW;AAAA,EACrB,OAEA;AACI,oBAAgB,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,EAC3C;AAEA,QAAM,SAAS;AACf,QAAM,KAAK,MAAM,QAAQ,CAAC,EAAE,WAAW;AAEvC,SAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AACrC;AAEA,SAAS,iBAAiB,OAAO,OACjC;AACI,UAAQ,OAAO,KAAK,SAAS,QAAQ,MAAM,KAAK;AAEhD,MAAI,QAAQ,MAAM,QAAQ,GAC1B;AACI,UAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,CAAC;AACxC,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,UAAM,KAAK,KAAK,IAAI;AACpB,UAAM,KAAK,MAAM,QAAQ,CAAC,IAAI;AAC9B,UAAM,SAAS;AAEf,WAAO,MAAM;AAAA,EACjB;AACA,QAAM,SAAS;AAEf,SAAO;AACX;AAEO,SAAS,gBAAgB,OAAO,OACvC;AACI,SAAO,iBAAiB,OAAO,KAAK;AACxC;AAEO,SAAS,kBAAkB,OAAO,OACzC;AACI,SAAO,iBAAiB,OAAO,KAAK;AACxC;AAEO,SAAS,gBAAgB,OAAO,OACvC;AACI,SAAO,iBAAiB,OAAO,KAAK;AACxC;AAEO,SAAS,cAAc,OAAO,OACrC;AACI,SAAO,iBAAiB,OAAO,KAAK;AACxC;AAEO,SAAS,eAAe,OAAO,OACtC;AACI,SAAO,iBAAiB,OAAO,KAAK;AACxC;;;ACpRA,IAAM,aAAa,CAAC,GAAG,OAAQ,IAAI,QAAS,IAAM,IAAI;AAEtD,IAAM,KAAK,IAAI,YAAY,IAAI,OAAO,GAAG,IAAI,MAAM,CAAC;AACpD,IAAM,MAAM,IAAI,YAAY,IAAI,OAAO,GAAG,IAAI,MAAM,CAAC;AACrD,IAAMC,MAAK,IAAI,OAAO;AACtB,IAAM,KAAK,IAAI,OAAO;AACtB,IAAM,KAAK,IAAI,OAAO;AACtB,IAAM,KAAK,IAAI,OAAO;AAEtB,SAAS,cAAcA,KAAIC,KAAI,QAC/B;AACI,QAAM,OAAO,mBAAmB,MAAMA,KAAID,GAAE,CAAC;AAC7C,QAAM,SAAS,YAAY,IAAI;AAE/B,QAAM,QAAQ,IAAI,UAAU;AAC5B,QAAM,WAAW,CAAEA,KAAIC,GAAG;AAC1B,QAAM,WAAW,OAAOD,KAAIC,KAAI,GAAG;AACnC,QAAM,UAAU,CAAE,QAAQ,MAAM,MAAM,CAAE;AACxC,QAAM,QAAQ;AACd,QAAM,SAAS;AAEf,SAAO;AACX;AAcO,SAAS,iBAAiB,SAAS,KAAK,SAAS,KAAK,UAC7D;AAGI,wBAAsB,KAAK,KAAK,EAAE;AAElC,QAAM,SAAS,QAAQ;AAGvB,QAAM,UAAW,GAAG,EAAE,IAAI,QAAQ,OAAO,IAAI,GAAG,EAAE,IAAI,QAAQ,OAAO,IAAK,GAAG,EAAE;AAC/E,QAAM,UAAW,GAAG,EAAE,IAAI,QAAQ,OAAO,IAAI,GAAG,EAAE,IAAI,QAAQ,OAAO,IAAK,GAAG,EAAE;AAE/E,QAAM,KAAK,UAAU,OAAO;AAC5B,QAAM,KAAK,UAAU,OAAO;AAC5B,QAAM,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAC5C,MAAI,UAAU,GACV,UAAU;AAEd,MAAI,YAAY,KAChB;AACI,cAAU,KAAK;AACf,cAAU,KAAK;AAAA,EACnB;AACA,QAAM,UAAU,QAAQ;AACxB,QAAM,UAAU,QAAQ;AACxB,QAAM,aAAa,WAAW,UAAU;AAExC,MAAI,aAAa,wBACjB;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AACA,QAAM,MAAM,OAAO,IAAI,UAAU;AACjC,QAAM,MAAM,OAAO,IAAI,UAAU;AACjC,QAAM,MAAM,UAAW,CAAC,UAAW;AACnC,QAAM,MAAM,UAAW,CAAC,UAAW;AACnC,QAAM,iBAAiB,MAAM,OAAO,MAAM;AAC1C,QAAM,iBAAiB,MAAM,OAAO,MAAM;AAC1C,WAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,WAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,WAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,WAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,QAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,KAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,KAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,aAAa;AAChB,KAAG,KAAK;AACR,WAAS,aAAa;AAEtB,SAAO;AACX;AAcO,SAAS,0BAA0B,UAAU,KAAK,SAAS,KAAK,UACvE;AAGI,wBAAsB,KAAK,KAAK,EAAE;AAGlC,QAAM,KAAK,iBAAiB,IAAI,QAAQ,MAAM;AAG9C,QAAMD,MAAK,SAAS;AACpB,QAAMC,MAAK,SAAS;AAEpB,QAAM,IAAI,MAAMA,KAAID,GAAE;AAKtB,MAAI;AACJ,QAAM,KAAK,MAAM,MAAM,IAAIA,GAAE,GAAG,CAAC;AACjC,QAAM,KAAK,MAAM,MAAMC,KAAI,EAAE,GAAG,CAAC;AAEjC,MAAI,KAAK,GACT;AAEI,SAAKD;AAAA,EACT,WACS,KAAK,GACd;AAEI,SAAKC;AAAA,EACT,OAEA;AAEI,UAAM,IAAI,KAAK,MAAM,GAAG,CAAC;AACzB,SAAK,SAASD,KAAI,GAAG,CAAC;AAAA,EAC1B;AAEA,QAAM,MAAM,wBAAwB,MAAM,IAAI,EAAE,CAAC;AACjD,QAAM,WAAW,IAAI;AACrB,QAAM,SAAS,IAAI;AAEnB,QAAM,UAAU,SAAS;AACzB,QAAM,UAAU,QAAQ;AACxB,QAAM,aAAa,WAAW,UAAU;AAExC,MAAI,aAAa,wBACjB;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAEA,QAAM,KAAK,SAAS,IAAI,SAAS,MAAM;AACvC,QAAM,KAAK,SAAS,IAAI,CAAC,SAAS,MAAM;AACxC,QAAM,gBAAgB,OAAO,IAAI,IAAI,GAAG;AAGxC,WAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AACzD,WAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AACzD,QAAM,KAAK,SAAS,OAAO,CAAC;AAG5B,KAAG,WAAW,IAAI,EAAE,IAAI,cAAc,IAAI,IAAI,EAAE,IAAI,cAAc;AAClE,KAAG,WAAW,IAAI,EAAE,IAAI,cAAc,IAAI,IAAI,EAAE,IAAI,cAAc;AAGlE,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAG7C,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,aAAa;AAChB,KAAG,KAAK;AACR,WAAS,aAAa;AAEtB,SAAO;AACX;AAEA,IAAM,IAAI,IAAI,OAAO;AAkBd,SAAS,0BAA0B,UAAU,KAAK,SAAS,KAAK,UACvE;AACI,QAAM,sBAAsB;AAE5B,wBAAsB,KAAK,KAAK,EAAE;AAGlC,sBAAoB,IAAI,QAAQ,QAAQ,CAAC;AACzC,QAAM,UAAU,SAAS;AACzB,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,UAAU;AAGzB,MAAI,cAAc;AAClB,MAAI,aAAa,CAAC,OAAO;AACzB,QAAM,cAAc,SAAS;AAC7B,QAAM,WAAW,SAAS;AAC1B,QAAM,UAAU,SAAS;AAEzB,WAAS,IAAI,GAAG,IAAI,aAAa,EAAE,GACnC;AAEI,UAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE;AAEnF,QAAI,IAAI,YACR;AACI,mBAAa;AACb,oBAAc;AAAA,IAClB;AAAA,EACJ;AAEA,MAAI,aAAa,SAAS,qBAC1B;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAGA,QAAM,aAAa;AACnB,QAAM,aAAa,aAAa,IAAI,cAAc,aAAa,IAAI;AACnE,QAAM,KAAK,SAAS,UAAU;AAC9B,QAAM,KAAK,SAAS,UAAU;AAG9B,QAAM,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG;AACpE,QAAM,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG;AAEpE,MAAI,KAAK,KAAO,aAAa,KAC7B;AAEI,UAAM,IAAI,EAAE,IAAI,GAAG;AACnB,UAAM,IAAI,EAAE,IAAI,GAAG;AACnB,UAAM,SAAS,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC;AACtC,QAAI,UAAU,GACV,UAAU;AAEd,QAAI,SAAS,KACb;AACI,YAAM,YAAY,IAAI;AACtB,gBAAU,IAAI;AACd,gBAAU,IAAI;AAAA,IAClB;AAEA,kBAAc,EAAE,IAAI,GAAG,KAAK,WAAW,EAAE,IAAI,GAAG,KAAK;AAErD,QAAI,aAAa,SAAS,qBAC1B;AACI,aAAO,SAAS,MAAM;AAAA,IAC1B;AAEA,UAAM,MAAM,GAAG,IAAI,UAAU;AAC7B,UAAM,MAAM,GAAG,IAAI,UAAU;AAC7B,UAAM,MAAM,EAAE,IAAI,UAAU;AAC5B,UAAM,MAAM,EAAE,IAAI,UAAU;AAC5B,UAAM,iBAAiB,OAAO,MAAM;AACpC,UAAM,iBAAiB,OAAO,MAAM;AAEpC,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,UAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,cAAc,MAAM,OAAO,WAAW,MAAM,OAAO;AACtD,OAAG,KAAK;AACR,aAAS,aAAa;AAAA,EAC1B,WACS,KAAK,KAAO,aAAa,KAClC;AAEI,UAAM,IAAI,EAAE,IAAI,GAAG;AACnB,UAAM,IAAI,EAAE,IAAI,GAAG;AACnB,UAAM,SAAS,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC;AACtC,QAAI,UAAU,GACV,UAAU;AAEd,QAAI,SAAS,KACb;AACI,YAAM,YAAY,IAAI;AACtB,gBAAU,IAAI;AACd,gBAAU,IAAI;AAAA,IAClB;AAEA,kBAAc,EAAE,IAAI,GAAG,KAAK,WAAW,EAAE,IAAI,GAAG,KAAK;AAErD,QAAI,aAAa,SAAS,qBAC1B;AACI,aAAO,SAAS,MAAM;AAAA,IAC1B;AAEA,UAAM,MAAM,GAAG,IAAI,UAAU;AAC7B,UAAM,MAAM,GAAG,IAAI,UAAU;AAC7B,UAAM,MAAM,EAAE,IAAI,UAAU;AAC5B,UAAM,MAAM,EAAE,IAAI,UAAU;AAC5B,UAAM,iBAAiB,OAAO,MAAM;AACpC,UAAM,iBAAiB,OAAO,MAAM;AAEpC,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,UAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,cAAc,MAAM,OAAO,WAAW,MAAM,OAAO;AACtD,OAAG,KAAK;AACR,aAAS,aAAa;AAAA,EAC1B,OAEA;AAEI,UAAM,UAAU,QAAQ,WAAW,EAAE;AACrC,UAAM,UAAU,QAAQ,WAAW,EAAE;AACrC,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AACjD,aAAS,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AAGjD,UAAM,IAAI,YAAY,EAAE,IAAI,GAAG,KAAK,WAAW,EAAE,IAAI,GAAG,KAAK;AAC7D,UAAM,MAAM,EAAE,IAAI,IAAI;AACtB,UAAM,MAAM,EAAE,IAAI,IAAI;AAGtB,UAAM,MAAM,EAAE,IAAI,UAAU;AAC5B,UAAM,MAAM,EAAE,IAAI,UAAU;AAG5B,UAAM,kBAAkB,MAAM,OAAO;AACrC,UAAM,kBAAkB,MAAM,OAAO;AAGrC,UAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,IAAI;AACnD,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,OAAG,aAAa,aAAa;AAC7B,OAAG,KAAK;AACR,aAAS,aAAa;AAAA,EAC1B;AAEA,SAAO;AACX;AAsBO,SAAS,kBAAkB,UAAU,KAAK,UAAU,KAAK,UAChE;AACI,QAAM,SAAS,SAAS;AAMxB,cAAY,IAAI,GAAG,GAAG,eAAe,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;AAC1D,MAAI,IAAI,IAAI;AACZ,wBAAsB,KAAK,KAAK,EAAE;AAGlC,EAAAA,IAAG,IAAI;AACP,EAAAA,IAAG,IAAI;AAGP,KAAG,IAAI,SAAS,QAAQ,IAAI,OAAO;AACnC,KAAG,IAAI,SAAS,QAAQ,IAAI,OAAO;AAGnC,sBAAoB,IAAI,SAAS,SAAS,EAAE;AAG5C,sBAAoB,IAAI,SAAS,SAAS,EAAE;AAC5C,QAAM,MAAM,GAAG;AACf,QAAM,MAAM,GAAG;AACf,QAAM,MAAM,GAAG,IAAI,GAAG;AACtB,QAAM,MAAM,GAAG,IAAI,GAAG;AACtB,QAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,QAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,UAAQ,OAAO,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,QAAQ,GAAG,qCAAqC;AACvG,QAAM,KAAKA,IAAG,IAAI,GAAG;AACrB,QAAM,KAAKA,IAAG,IAAI,GAAG;AACrB,QAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,QAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,QAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,QAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,MAAI,KAAK;AAET,MAAI,UAAU,GACd;AACI,SAAK,cAAc,MAAM,MAAM,MAAM,OAAO,OAAO,GAAK,CAAG;AAAA,EAC/D;AACA,MAAI,MAAM,MAAM,KAAK,OAAO;AAE5B,MAAI,KAAK,GACT;AACI,SAAK;AACL,SAAK,aAAa,CAAC,MAAM,KAAK,GAAK,CAAG;AAAA,EAC1C,WACS,KAAK,GACd;AACI,SAAK;AACL,SAAK,cAAc,MAAM,OAAO,KAAK,GAAK,CAAG;AAAA,EACjD;AAGA,QAAM,WAAW,EAAE,GAAGA,IAAG,IAAI,KAAK,KAAK,GAAGA,IAAG,IAAI,KAAK,IAAI;AAG1D,QAAM,WAAW,EAAE,GAAG,GAAG,IAAI,KAAK,KAAK,GAAG,GAAG,IAAI,KAAK,IAAI;AAC1D,QAAM,kBAAkB,kBAAkB,UAAU,QAAQ;AAC5D,QAAM,UAAU,SAAS;AACzB,QAAM,UAAU,SAAS;AACzB,QAAM,SAAS,UAAU;AACzB,QAAM,cAAc,SAAS;AAE7B,MAAI,kBAAkB,cAAc,aACpC;AACI,oBAAgB,QAAQ;AAExB;AAAA,EACJ;AACA,QAAM,WAAW,KAAK,KAAK,eAAe;AAC1C,QAAM,UAAU,WAAW,KAAK,GAAG;AACnC,QAAM,MAAM,MAAM,IAAM;AACxB,QAAM,MAAM,MAAM,IAAM;AACxB,QAAM,UAAU,WAAW,KAAK,GAAG;AACnC,QAAM,MAAM,MAAM,IAAM;AACxB,QAAM,MAAM,MAAM,IAAM;AAGxB,QAAM,OAAO,GAAG,IAAIA,IAAG,KAAK,OAAO,GAAG,IAAIA,IAAG,KAAK;AAClD,QAAM,OAAO,GAAG,IAAIA,IAAG,KAAK,OAAO,GAAG,IAAIA,IAAG,KAAK;AAClD,QAAM,WAAY,OAAO,KAAO,OAAO,KAAS,OAAO,WAAW,OAAO;AAIzE,QAAM,OAAOA,IAAG,IAAI,GAAG,KAAK,OAAOA,IAAG,IAAI,GAAG,KAAK;AAClD,QAAM,OAAO,GAAG,IAAI,GAAG,KAAK,OAAO,GAAG,IAAI,GAAG,KAAK;AAClD,QAAM,WAAY,OAAO,KAAO,OAAO,KAAS,OAAO,WAAW,OAAO;AAEzE,WAAS,aAAa;AAEtB,MAAI,aAAa,SAAS,aAAa,OACvC;AACI,QAAI,UAAU,UAAU;AAExB;AAEI,iBAAW,CAAC;AACZ,iBAAW;AAIX,YAAM,OAAO,GAAG,IAAIA,IAAG,KAAK,YAAY,GAAG,IAAIA,IAAG,KAAK;AACvD,YAAM,OAAO,GAAG,IAAIA,IAAG,KAAK,YAAY,GAAG,IAAIA,IAAG,KAAK;AACvD,YAAM,MAAM,KAAK,IAAI,KAAK,GAAG;AAC7B,YAAM,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG;AAE/B,UAAI,MAAM,KACV;AACI,sBAAc;AAAA,MAClB,OAEA;AACI,sBAAc;AAGd,mBAAW,CAAC;AACZ,mBAAW,CAAC;AAAA,MAChB;AAAA,IACJ;AACA,QAAI,UAAU,UAAU;AAExB;AAEI,iBAAW,CAAC;AACZ,iBAAW;AAIX,YAAM,OAAOA,IAAG,IAAI,GAAG,KAAK,YAAYA,IAAG,IAAI,GAAG,KAAK;AACvD,YAAM,OAAO,GAAG,IAAI,GAAG,KAAK,YAAY,GAAG,IAAI,GAAG,KAAK;AACvD,YAAM,MAAM,KAAK,IAAI,KAAK,GAAG;AAC7B,YAAM,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG;AAE/B,UAAI,MAAM,KACV;AACI,sBAAc;AAAA,MAClB,OAEA;AACI,sBAAc;AAGd,mBAAW,CAAC;AACZ,mBAAW,CAAC;AAAA,MAChB;AAAA,IACJ;AAEA,QAAI,eAAe,aACnB;AACI,eAAS,UAAU;AACnB,eAAS,UAAU;AACnB,UAAI,MAAM,GAAG;AACb,UAAI,MAAM,GAAG;AACb,UAAI,MAAM,GAAG;AACb,UAAI,MAAM,GAAG;AAEb,UAAI,MAAM,KAAO,MAAM,GACvB;AACI,cAAM,KAAK,IAAM,QAAQ,MAAM;AAC/B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAAA,MAChC,WACS,MAAM,KAAO,MAAM,GAC5B;AACI,cAAM,KAAK,IAAM,QAAQ,MAAM;AAC/B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAAA,MAChC;AAEA,UAAI,MAAM,WAAW,MAAM,SAC3B;AACI,cAAM,KAAK,MAAM,YAAY,MAAM;AACnC,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAAA,MAChC,WACS,MAAM,WAAW,MAAM,SAChC;AACI,cAAM,KAAK,MAAM,YAAY,MAAM;AACnC,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAAA,MAChC;AAIA,YAAM,MAAM,MAAMA,IAAG,KAAK,YAAY,MAAMA,IAAG,KAAK;AACpD,YAAM,MAAM,MAAMA,IAAG,KAAK,YAAY,MAAMA,IAAG,KAAK;AAEpD,UAAI,MAAM,WAAW,iBAAiB,MAAM,WAAW,eACvD;AACI,YAAI,IAAI,OAAO,UAAU,UAAU;AACnC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,aAAa,KAAK;AACrC,iBAAS,OAAO,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC;AACvC,YAAI,OAAO,UAAU,UAAU;AAC/B,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,aAAa,KAAK;AACrC,iBAAS,OAAO,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC;AACvC,iBAAS,aAAa;AAAA,MAC1B;AAAA,IACJ,OAEA;AACI,eAAS,UAAU,CAAC;AACpB,eAAS,UAAU,CAAC;AACpB,UAAI,MAAMA,IAAG;AACb,UAAI,MAAMA,IAAG;AACb,UAAI,MAAM,GAAG;AACb,UAAI,MAAM,GAAG;AAEb,UAAI,MAAM,KAAO,MAAM,GACvB;AACI,cAAM,KAAK,IAAM,QAAQ,MAAM;AAC/B,cAAMA,IAAG,IAAI,KAAK,GAAG,IAAIA,IAAG;AAC5B,cAAMA,IAAG,IAAI,KAAK,GAAG,IAAIA,IAAG;AAAA,MAChC,WACS,MAAM,KAAO,MAAM,GAC5B;AACI,cAAM,KAAK,IAAM,QAAQ,MAAM;AAC/B,cAAM,GAAG,IAAI,KAAKA,IAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAKA,IAAG,IAAI,GAAG;AAAA,MAChC;AAEA,UAAI,MAAM,WAAW,MAAM,SAC3B;AACI,cAAM,KAAK,MAAM,YAAY,MAAM;AACnC,cAAMA,IAAG,IAAI,KAAK,GAAG,IAAIA,IAAG;AAC5B,cAAMA,IAAG,IAAI,KAAK,GAAG,IAAIA,IAAG;AAAA,MAChC,WACS,MAAM,WAAW,MAAM,SAChC;AACI,cAAM,KAAK,MAAM,YAAY,MAAM;AACnC,cAAM,GAAG,IAAI,KAAKA,IAAG,IAAI,GAAG;AAC5B,cAAM,GAAG,IAAI,KAAKA,IAAG,IAAI,GAAG;AAAA,MAChC;AACA,YAAM,MAAM,MAAM,GAAG,KAAK,YAAY,MAAM,GAAG,KAAK;AACpD,YAAM,MAAM,MAAM,GAAG,KAAK,YAAY,MAAM,GAAG,KAAK;AAEpD,UAAI,MAAM,WAAW,iBAAiB,MAAM,WAAW,eACvD;AACI,YAAI,IAAI,OAAO,UAAU,UAAU;AACnC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,aAAa,KAAK;AACrC,iBAAS,OAAO,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC;AAEvC,YAAI,OAAO,UAAU,UAAU;AAC/B,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,WAAW,MAAM,IAAI;AACxC,iBAAS,OAAO,CAAC,EAAE,aAAa,KAAK;AACrC,iBAAS,OAAO,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC;AACvC,iBAAS,aAAa;AAAA,MAC1B;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,SAAS,eAAe,GAC5B;AACI,QAAI,UAAU,SAAS,IAAI,SAAS;AACpC,QAAI,UAAU,SAAS,IAAI,SAAS;AACpC,UAAM,WAAW,UAAU,UAAU,UAAU;AAE/C,QAAI,WAAW,QACf;AACI,YAAM,SAAS,KAAK,KAAK,QAAQ;AACjC,iBAAW;AACX,iBAAW;AAAA,IACf,OAEA;AAEI,gBAAU,CAAC;AACX,gBAAU;AAAA,IACd;AACA,UAAM,MAAM,SAAS,IAAI,UAAU;AACnC,UAAM,MAAM,SAAS,IAAI,UAAU;AACnC,UAAM,MAAM,SAAS,IAAI,UAAU;AACnC,UAAM,MAAM,SAAS,IAAI,UAAU;AACnC,UAAM,KAAK,OAAO,IAAM,IAAI;AAC5B,UAAM,KAAK,OAAO,IAAM,IAAI;AAC5B,aAAS,UAAU;AACnB,aAAS,UAAU;AACnB,aAAS,OAAO,CAAC,EAAE,YAAY,MAAM,OAAO;AAC5C,aAAS,OAAO,CAAC,EAAE,YAAY,MAAM,OAAO;AAC5C,aAAS,OAAO,CAAC,EAAE,aAAa,KAAK,KAAK,eAAe,IAAI;AAC7D,aAAS,OAAO,CAAC,EAAE,KAAK,WAAW,IAAI,EAAE;AACzC,aAAS,aAAa;AAAA,EAC1B;AAEA,MAAI,SAAS,aAAa,GAC1B;AACI,UAAM,iBAAiB,IAAI,EAAE,IAAI,SAAS,UAAU,IAAI,EAAE,IAAI,SAAS;AACvE,UAAM,iBAAiB,IAAI,EAAE,IAAI,SAAS,UAAU,IAAI,EAAE,IAAI,SAAS;AACvE,aAAS,UAAU;AACnB,aAAS,UAAU;AAEnB,aAAS,IAAI,GAAG,IAAI,SAAS,YAAY,EAAE,GAC3C;AACI,YAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,YAAM,KAAK,GAAG,WAAW,OAAO;AAChC,YAAM,KAAK,GAAG,WAAW,OAAO;AAChC,YAAM,cAAc,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI;AAC7C,YAAM,cAAc,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI;AAC7C,SAAG,WAAW;AACd,SAAG,WAAW;AACd,SAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,SAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,SAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,SAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AAAA,IAC7B;AAAA,EACJ;AAEA;AACJ;AAEA,IAAM,eAAe,IAAI,UAAU;AAc5B,SAAS,2BAA2B,UAAU,KAAK,UAAU,KAAK,UACzE;AACI,eAAa,UAAU,SAAS;AAChC,eAAa,UAAU,SAAS;AAChC,eAAa,SAAS;AAEtB,SAAO,kBAAkB,cAAc,KAAK,UAAU,GAAG;AAC7D;AAcO,SAAS,2BAA2B,UAAU,KAAK,UAAU,KAAK,UACzE;AACI,QAAM,QAAQ,cAAc,SAAS,SAAS,SAAS,SAAS,SAAS,MAAM;AAE/E,SAAO,kBAAkB,UAAU,KAAK,OAAO,KAAK,QAAQ;AAChE;AAGA,SAAS,eAAe,OAAO,OAAO,OAAO,OAAO,MAAM,UAC1D;AAEI,MAAI,OAAO,KAAK;AAGhB,MAAI,OAAO,KAAK;AAEhB,MAAI,MACJ;AACI,YAAQ;AACR,YAAQ;AACR,UAAM;AACN,UAAM,QAAQ,IAAI,MAAM,QAAQ,QAAQ,IAAI;AAC5C,UAAM;AACN,UAAM,QAAQ,IAAI,MAAM,QAAQ,QAAQ,IAAI;AAAA,EAChD,OAEA;AACI,YAAQ;AACR,YAAQ;AACR,UAAM;AACN,UAAM,QAAQ,IAAI,MAAM,QAAQ,QAAQ,IAAI;AAC5C,UAAM;AACN,UAAM,QAAQ,IAAI,MAAM,QAAQ,QAAQ,IAAI;AAAA,EAChD;AAEA,QAAM,SAAS,MAAM,QAAQ,GAAG;AAGhC,QAAM,MAAM,MAAM,SAAS,GAAG;AAC9B,QAAM,MAAM,MAAM,SAAS,GAAG;AAG9B,QAAM,MAAM,MAAM,SAAS,GAAG;AAC9B,QAAM,MAAM,MAAM,SAAS,GAAG;AAG9B,QAAM,WAAW,KAAO,OAAO;AAC/B,QAAM,WAAW,IAAM,OAAO;AAE9B,QAAM,SAAS;AAGf,MAAI,OAAO,IAAI,IAAI,IAAI;AACvB,MAAI,OAAO,IAAI,IAAI,IAAI;AACvB,QAAM,SAAS,OAAO,WAAW,OAAO;AAIxC,SAAO,IAAI,IAAI,IAAI;AACnB,SAAO,IAAI,IAAI,IAAI;AACnB,QAAM,SAAS,OAAO,WAAW,OAAO;AAGxC,SAAO,IAAI,IAAI,IAAI;AACnB,SAAO,IAAI,IAAI,IAAI;AACnB,QAAM,SAAS,OAAO,WAAW,OAAO;AAExC,MAAI;AAEJ,MAAI,SAAS,UAAU,SAAS,SAAS,KACzC;AACI,aAAS,OAAO,KAAK,MAAM,SAAS,WAAW,SAAS,OAAO;AAAA,EACnE,OAEA;AACI,aAAS;AAAA,EACb;AAEA,MAAI;AAEJ,MAAI,SAAS,UAAU,SAAS,SAAS,KACzC;AACI,aAAS,OAAO,KAAK,MAAM,SAAS,WAAW,SAAS,OAAO;AAAA,EACnE,OAEA;AACI,aAAS;AAAA,EACb;AAIA,QAAM,kBAAkB,SAAS,QAAQ,KAAK,MAAM;AACpD,QAAM,kBAAkB,SAAS,QAAQ,KAAK,MAAM;AAEpD,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,MAAM;AAKjB,cAAY,QAAQ,OAAO,KAAK,KAAK,kBAAkB,QAAQA,GAAE;AACjE,cAAY,QAAQ,OAAO,KAAK,KAAK,kBAAkB,QAAQ,EAAE;AAEjE,QAAM,SAAS,KAAK;AAEpB,MAAI,SAAS,OACb;AACI,aAAS,UAAU,OAAO;AAC1B,aAAS,UAAU,OAAO;AAC1B,QAAI,KAAK,SAAS,OAAO,CAAC;AAC1B,OAAG,WAAWA,IAAG;AACjB,OAAG,WAAWA,IAAG;AACjB,OAAG,aAAa,kBAAkB;AAClC,OAAG,KAAK,WAAW,KAAK,GAAG;AAE3B,SAAK,SAAS,OAAO,CAAC;AACtB,OAAG,WAAW,GAAG;AACjB,OAAG,WAAW,GAAG;AACjB,OAAG,aAAa,kBAAkB;AAClC,OAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,aAAS,aAAa;AAAA,EAC1B,OAEA;AAEI,aAAS,UAAU,CAAC,OAAO;AAC3B,aAAS,UAAU,CAAC,OAAO;AAC3B,QAAI,KAAK,SAAS,OAAO,CAAC;AAC1B,OAAG,WAAW,GAAG;AACjB,OAAG,WAAW,GAAG;AACjB,OAAG,aAAa,kBAAkB;AAClC,OAAG,KAAK,WAAW,KAAK,GAAG;AAE3B,SAAK,SAAS,OAAO,CAAC;AACtB,OAAG,WAAWA,IAAG;AACjB,OAAG,WAAWA,IAAG;AACjB,OAAG,aAAa,kBAAkB;AAClC,OAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,aAAS,aAAa;AAAA,EAC1B;AAEA,SAAO;AACX;AAGA,SAAS,oBAAoB,OAAO,OACpC;AACI,QAAM,SAAS,MAAM;AACrB,QAAM,SAAS,MAAM;AACrB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,MAAM;AAElB,MAAI,YAAY;AAChB,MAAI,gBAAgB,OAAO;AAE3B,WAAS,IAAI,GAAG,IAAI,QAAQ,EAAE,GAC9B;AAEI,UAAM,IAAI,IAAI,CAAC;AACf,UAAM,KAAK,IAAI,CAAC,EAAE,GACd,KAAK,IAAI,CAAC,EAAE;AAGhB,QAAI,KAAK,OAAO;AAEhB,aAAS,IAAI,GAAG,IAAI,QAAQ,EAAE,GAC9B;AACI,YAAM,KAAK,IAAI,CAAC,EAAE,IAAI;AACtB,YAAM,KAAK,IAAI,CAAC,EAAE,IAAI;AACtB,YAAM,MAAM,EAAE,IAAI,KAAK,EAAE,IAAI;AAG7B,UAAI,MAAM,IACV;AACI,aAAK;AAAA,MACT;AAAA,IACJ;AAEA,QAAI,KAAK,eACT;AACI,sBAAgB;AAChB,kBAAY;AAAA,IAChB;AAAA,EACJ;AAEA,SAAO,EAAE,WAAW,WAAW,cAA6B;AAChE;AAoBA,IAAM,aAAa,IAAI,UAAU,uBAAuB;AACxD,IAAM,aAAa,IAAI,UAAU,uBAAuB;AACxD,IAAME,KAAI,IAAI,OAAO;AACrB,IAAM,MAAM,IAAI,YAAY;AAkBrB,SAAS,kBAAkB,UAAU,KAAK,UAAU,KAAK,UAChE;AACI,QAAM,UAAU,SAAS,SAAS,CAAC,EAAE;AACrC,QAAM,UAAU,SAAS,SAAS,CAAC,EAAE;AAErC,EAAAA,GAAE,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AAC/C,EAAAA,GAAE,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI;AAC/C,MAAI,IAAIA;AACR,MAAI,IAAI,IAAI;AACZ,wBAAsB,KAAK,KAAK,EAAE;AAGlC,aAAW,WAAW;AAEtB,aAAW,QAAQ,SAAS;AAC5B,aAAW,SAAS,SAAS;AAC7B,aAAW,SAAS,CAAC,EAAE,IAAI;AAC3B,aAAW,SAAS,CAAC,EAAE,IAAI;AAC3B,aAAW,QAAQ,CAAC,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AAC9C,aAAW,QAAQ,CAAC,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AAE9C,WAAS,IAAI,GAAG,IAAI,WAAW,OAAO,EAAE,GACxC;AACI,UAAM,IAAI,WAAW,SAAS,CAAC;AAC/B,MAAE,IAAI,SAAS,SAAS,CAAC,EAAE,IAAI;AAC/B,MAAE,IAAI,SAAS,SAAS,CAAC,EAAE,IAAI;AAC/B,UAAM,IAAI,WAAW,QAAQ,CAAC;AAC9B,MAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AAC1B,MAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AAAA,EAC9B;AAGA,aAAW,WAAW;AAEtB,aAAW,QAAQ,SAAS;AAC5B,aAAW,SAAS,SAAS;AAE7B,WAAS,IAAI,GAAG,IAAI,WAAW,OAAO,EAAE,GACxC;AACI,UAAM,IAAI,WAAW,SAAS,CAAC;AAC/B,UAAMA,KAAI,SAAS,SAAS,CAAC;AAC7B,MAAE,IAAK,GAAG,EAAE,IAAIA,GAAE,IAAI,GAAG,EAAE,IAAIA,GAAE,IAAK,GAAG,EAAE;AAC3C,MAAE,IAAK,GAAG,EAAE,IAAIA,GAAE,IAAI,GAAG,EAAE,IAAIA,GAAE,IAAK,GAAG,EAAE;AAC3C,UAAM,IAAI,WAAW,QAAQ,CAAC;AAC9B,MAAE,IAAI,GAAG,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE,IAAI,GAAG,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AACpE,MAAE,IAAI,GAAG,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE,IAAI,GAAG,EAAE,IAAI,SAAS,QAAQ,CAAC,EAAE;AAAA,EACxE;AAEA,QAAM,OAAO,oBAAoB,YAAY,UAAU;AACvD,MAAI,QAAQ,KAAK;AACjB,QAAM,cAAc,KAAK;AAEzB,QAAM,OAAO,oBAAoB,YAAY,UAAU;AACvD,MAAI,QAAQ,KAAK;AACjB,QAAM,cAAc,KAAK;AAEzB,QAAM,SAAS,WAAW,SAAS,WAAW;AAE9C,MAAI,cAAc,yBAAyB,UAAU,cAAc,yBAAyB,QAC5F;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAGA,MAAI;AAEJ,MAAI,eAAe,aACnB;AACI,WAAO;AAEP,UAAM,kBAAkB,WAAW,QAAQ,KAAK;AAGhD,UAAM,QAAQ,WAAW;AACzB,UAAM,UAAU,WAAW;AAC3B,YAAQ;AACR,QAAI,SAAS,OAAO;AAEpB,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,MAAM,gBAAgB,IAAI,QAAQ,CAAC,EAAE,IAAI,gBAAgB,IAAI,QAAQ,CAAC,EAAE;AAE9E,UAAI,MAAM,QACV;AACI,iBAAS;AACT,gBAAQ;AAAA,MACZ;AAAA,IACJ;AAAA,EACJ,OAEA;AACI,WAAO;AAEP,UAAM,kBAAkB,WAAW,QAAQ,KAAK;AAGhD,UAAM,QAAQ,WAAW;AACzB,UAAM,UAAU,WAAW;AAC3B,YAAQ;AACR,QAAI,SAAS,OAAO;AAEpB,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,MAAM,gBAAgB,IAAI,QAAQ,CAAC,EAAE,IAAI,gBAAgB,IAAI,QAAQ,CAAC,EAAE;AAE9E,UAAI,MAAM,QACV;AACI,iBAAS;AACT,gBAAQ;AAAA,MACZ;AAAA,IACJ;AAAA,EACJ;AAMA,MAAI,cAAc,MAAM,iBAAiB,cAAc,MAAM,eAC7D;AAGI,UAAM,MAAM;AACZ,UAAM,MAAM,QAAQ,IAAI,WAAW,QAAQ,QAAQ,IAAI;AACvD,UAAM,MAAM;AACZ,UAAM,MAAM,QAAQ,IAAI,WAAW,QAAQ,QAAQ,IAAI;AAEvD,UAAM,MAAM,WAAW,SAAS,GAAG;AACnC,UAAM,MAAM,WAAW,SAAS,GAAG;AACnC,UAAM,MAAM,WAAW,SAAS,GAAG;AACnC,UAAM,MAAM,WAAW,SAAS,GAAG;AAEnC,UAAM,SAAS,kBAAkB,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAQvF,QAAI,OAAO,cAAc,KAAO,OAAO,cAAc,GACrD;AAEI,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,cAAQ,OAAO,OAAO,kBAAkB,CAAG;AAC3C,YAAM,WAAW,KAAK,KAAK,OAAO,eAAe;AAEjD,UAAI,WAAW,yBAAyB,QACxC;AACI,eAAO,SAAS,MAAM;AAAA,MAC1B;AACA,YAAM,cAAc,IAAM;AAC1B,iBAAW;AACX,iBAAW;AAEX,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AAGxC,eAAS,UAAU;AACnB,eAAS,UAAU;AACnB,YAAM,KAAK,SAAS,OAAO,CAAC;AAC5B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,aAAa,WAAW;AAC3B,SAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,eAAS,aAAa;AAAA,IAC1B,WACS,OAAO,cAAc,KAAO,OAAO,cAAc,GAC1D;AAEI,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,cAAQ,OAAO,OAAO,kBAAkB,CAAG;AAC3C,YAAM,WAAW,KAAK,KAAK,OAAO,eAAe;AAEjD,UAAI,WAAW,yBAAyB,QACxC;AACI,eAAO,SAAS,MAAM;AAAA,MAC1B;AACA,YAAM,cAAc,IAAM;AAC1B,iBAAW;AACX,iBAAW;AAEX,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AAExC,eAAS,UAAU;AACnB,eAAS,UAAU;AACnB,YAAM,KAAK,IAAI,gBAAgB;AAC/B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,aAAa,WAAW;AAC3B,SAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,eAAS,OAAO,CAAC,IAAI;AACrB,eAAS,aAAa;AAAA,IAC1B,WACS,OAAO,cAAc,KAAO,OAAO,cAAc,GAC1D;AAEI,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,cAAQ,OAAO,OAAO,kBAAkB,CAAG;AAC3C,YAAM,WAAW,KAAK,KAAK,OAAO,eAAe;AAEjD,UAAI,WAAW,yBAAyB,QACxC;AACI,eAAO,SAAS,MAAM;AAAA,MAC1B;AACA,YAAM,cAAc,IAAM;AAC1B,iBAAW;AACX,iBAAW;AAEX,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AAExC,eAAS,UAAU;AACnB,eAAS,UAAU;AACnB,YAAM,KAAK,IAAI,gBAAgB;AAC/B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,aAAa,WAAW;AAC3B,SAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,eAAS,OAAO,CAAC,IAAI;AACrB,eAAS,aAAa;AAAA,IAC1B,WACS,OAAO,cAAc,KAAO,OAAO,cAAc,GAC1D;AAEI,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,UAAI,UAAU,IAAI,IAAI,IAAI;AAC1B,cAAQ,OAAO,OAAO,kBAAkB,CAAG;AAC3C,YAAM,WAAW,KAAK,KAAK,OAAO,eAAe;AAEjD,UAAI,WAAW,yBAAyB,QACxC;AACI,eAAO,SAAS,MAAM;AAAA,MAC1B;AACA,YAAM,cAAc,IAAM;AAC1B,iBAAW;AACX,iBAAW;AAEX,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AACxC,YAAM,MAAM,IAAI,IAAI,WAAW,SAAS;AAExC,eAAS,UAAU;AACnB,eAAS,UAAU;AACnB,YAAM,KAAK,IAAI,gBAAgB;AAC/B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,YAAY,MAAM,OAAO;AAC5B,SAAG,aAAa,WAAW;AAC3B,SAAG,KAAK,WAAW,KAAK,GAAG;AAC3B,eAAS,OAAO,CAAC,IAAI;AACrB,eAAS,aAAa;AAAA,IAC1B,OAEA;AAEI,qBAAe,YAAY,YAAY,OAAO,OAAO,MAAM,QAAQ;AAAA,IACvE;AAAA,EACJ,OAEA;AAEI,mBAAe,YAAY,YAAY,OAAO,OAAO,MAAM,QAAQ;AAAA,EACvE;AAGA,MAAI,SAAS,aAAa,GAC1B;AACI,UAAM,OAAO,SAAS;AACtB,aAAS,UAAU,IAAI,EAAE,IAAI,SAAS,UAAU,IAAI,EAAE,IAAI,SAAS;AACnE,aAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,SAAS;AAEvD,aAAS,IAAI,GAAG,IAAI,SAAS,YAAY,EAAE,GAC3C;AACI,YAAM,KAAK,SAAS,OAAO,CAAC;AAE5B,YAAM,OAAO,GAAG,WAAW;AAC3B,YAAM,OAAO,GAAG,WAAW;AAC3B,SAAG,WAAW,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI;AACzC,SAAG,WAAW,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI;AACzC,SAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,SAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,SAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,SAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AAAA,IAC7B;AAAA,EACJ;AAEA,SAAO;AACX;AAcO,SAAS,0BAA0B,UAAU,KAAK,SAAS,KAAK,UACvE;AACI,QAAM,WAAW,IAAI,UAAU;AAC/B,WAAS,UAAU,SAAS;AAC5B,WAAS,UAAU,SAAS;AAC5B,WAAS,SAAS;AAElB,SAAO,0BAA0B,UAAU,KAAK,SAAS,KAAK,QAAQ;AAC1E;AAcO,SAAS,2BAA2B,UAAU,KAAK,UAAU,KAAK,UACzE;AACI,QAAM,WAAW,cAAc,SAAS,QAAQ,SAAS,QAAQ,CAAG;AAEpE,SAAO,kBAAkB,UAAU,KAAK,UAAU,KAAK,QAAQ;AACnE;AAqBO,SAAS,+BAA+B,eAAe,KAAK,SAAS,KAAK,UACjF;AAGI,wBAAsB,KAAK,KAAK,EAAE;AAGlC,QAAM,KAAK,iBAAiB,IAAI,QAAQ,MAAM;AAE9C,QAAMF,MAAK,cAAc,QAAQ;AACjC,QAAMC,MAAK,cAAc,QAAQ;AACjC,QAAM,IAAI,MAAMA,KAAID,GAAE;AAGtB,QAAM,SAAS,MAAM,YAAY,CAAC,GAAG,MAAM,IAAIA,GAAE,CAAC;AAElD,MAAI,SAAS,GACb;AAEI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAGA,QAAM,IAAI,MAAM,GAAG,MAAMC,KAAI,EAAE,CAAC;AAChC,QAAM,IAAI,MAAM,GAAG,MAAM,IAAID,GAAE,CAAC;AAEhC,MAAI;AAEJ,MAAI,KAAK,GACT;AAGI,UAAM,WAAW,MAAMA,KAAI,cAAc,MAAM;AAC/C,UAAM,QAAQ,MAAM,UAAU,MAAM,IAAIA,GAAE,CAAC;AAE3C,QAAI,SAAS,GACb;AACI,aAAO,SAAS,MAAM;AAAA,IAC1B;AAEA,SAAKA;AAAA,EACT,WACS,KAAK,GACd;AAEI,UAAM,WAAW,MAAM,cAAc,QAAQC,GAAE;AAC/C,UAAM,QAAQ,MAAM,UAAU,MAAM,IAAIA,GAAE,CAAC;AAG3C,QAAI,QAAQ,GACZ;AACI,aAAO,SAAS,MAAM;AAAA,IAC1B;AAEA,SAAKA;AAAA,EACT,OAEA;AACI,UAAM,KAAK,MAAM,GAAG,CAAC;AACrB,SAAK,IAAI,OAAO,IAAID,IAAG,IAAI,IAAIC,IAAG,GAAG,IAAID,IAAG,IAAI,IAAIC,IAAG,CAAC;AACxD,SAAK,KAAK,IAAM,QAAQ,IAAM,IAAI,EAAE,IAAID;AAAA,EAC5C;AAEA,QAAM,MAAM,wBAAwB,MAAM,IAAI,EAAE,CAAC;AACjD,QAAM,WAAW,IAAI;AACrB,QAAM,SAAS,IAAI;AAEnB,QAAM,SAAS,QAAQ;AACvB,QAAM,aAAa,WAAW;AAE9B,MAAI,aAAa,wBACjB;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAEA,QAAM,KAAK;AACX,QAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,MAAM;AACvC,QAAM,gBAAgB,OAAO,IAAI,IAAI,GAAG;AAGxC,WAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AACzD,WAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AAEzD,QAAM,KAAK,SAAS,OAAO,CAAC;AAG5B,KAAG,WAAW,IAAI,EAAE,IAAI,cAAc,IAAI,IAAI,EAAE,IAAI,cAAc;AAClE,KAAG,WAAW,IAAI,EAAE,IAAI,cAAc,IAAI,IAAI,EAAE,IAAI,cAAc;AAGlE,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,KAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAG7C,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,KAAG,aAAa;AAChB,KAAG,KAAK;AACR,WAAS,aAAa;AAEtB,SAAO;AACX;AAeO,SAAS,gCAAgC,UAAU,KAAK,UAAU,KAAK,OAAO,UACrF;AACI,QAAM,QAAQ,cAAc,SAAS,SAAS,SAAS,SAAS,SAAS,MAAM;AAE/E,SAAO,gCAAgC,UAAU,KAAK,OAAO,KAAK,OAAO,QAAQ;AACrF;AAEA,SAAS,eAAe,IAAI,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI,KAAK,KAAK,UAClE;AACI,QAAM,UAAU,WAAW,MAAM;AAGjC,QAAM,SAAS;AACf,QAAM,SAAS,MAAM,MAAM,IAAI,EAAE,GAAG,OAAO;AAG3C,QAAM,SAAS,MAAM,MAAM,IAAI,EAAE,GAAG,OAAO;AAC3C,QAAM,SAAS,MAAM,MAAM,IAAI,EAAE,GAAG,OAAO;AAG3C,MAAI,SAAS,UAAU,SAAS,QAChC;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAEA,MAAI;AAEJ,MAAI,SAAS,UAAU,SAAS,SAAS,KACzC;AACI,aAAS,OAAO,IAAI,KAAK,SAAS,WAAW,SAAS,OAAO;AAAA,EACjE,OAEA;AACI,aAAS;AAAA,EACb;AAEA,MAAI;AAEJ,MAAI,SAAS,UAAU,SAAS,SAAS,KACzC;AACI,aAAS,OAAO,IAAI,KAAK,SAAS,WAAW,SAAS,OAAO;AAAA,EACjE,OAEA;AACI,aAAS;AAAA,EACb;AAIA,QAAM,kBAAkB,MAAM,MAAM,QAAQ,EAAE,GAAG,MAAM;AACvD,QAAM,kBAAkB,MAAM,MAAM,QAAQ,EAAE,GAAG,MAAM;AAGvD,WAAS,SAAS,QAAQ,OAAO,KAAK,KAAK,kBAAkB,MAAM;AACnE,WAAS,SAAS,QAAQ,OAAO,KAAK,KAAK,kBAAkB,MAAM;AAEnE,QAAM,SAAS,KAAK;AAEpB,WAAS,UAAU,OAAO;AAC1B,WAAS,UAAU,OAAO;AAE1B,QAAMG,MAAK,SAAS,OAAO,CAAC;AAC5B,EAAAA,IAAG,WAAW,OAAO;AACrB,EAAAA,IAAG,WAAW,OAAO;AACrB,EAAAA,IAAG,aAAa,kBAAkB;AAClC,EAAAA,IAAG,KAAK;AAER,QAAMH,MAAK,SAAS,OAAO,CAAC;AAG5B,EAAAA,IAAG,WAAW,OAAO;AACrB,EAAAA,IAAG,WAAW,OAAO;AACrB,EAAAA,IAAG,aAAa,kBAAkB;AAClC,EAAAA,IAAG,KAAK;AAER,WAAS,aAAa;AAEtB,SAAO;AACX;AAEA,IAAM,eAAe;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,eAAe;AACnB;AAEA,SAAS,iBAAiB,QAAQ,QAClC;AACI,QAAM,SAAS;AAEf,MAAI,MAAM,QAAQ,OAAO,KAAK,KAAK,GACnC;AAEI,QAAI,OAAO,SACX;AACI,UAAI,QAAQ,QAAQ,OAAO,OAAO,IAAI,QACtC;AACI,eAAO,aAAa;AAAA,MACxB;AAEA,aAAO,aAAa;AAAA,IACxB,OAEA;AACI,aAAO,aAAa;AAAA,IACxB;AAAA,EACJ,OAEA;AAEI,QAAI,OAAO,SACX;AACI,UAAI,QAAQ,OAAO,SAAS,MAAM,IAAI,QACtC;AACI,eAAO,aAAa;AAAA,MACxB;AAEA,aAAO,aAAa;AAAA,IACxB,OAEA;AACI,aAAO,aAAa;AAAA,IACxB;AAAA,EACJ;AACJ;AAEA,IAAM,uBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ,IAAI,OAAO;AACxB,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,EAEnB;AACJ;AAiBO,SAAS,gCAAgC,eAAe,KAAK,UAAU,KAAK,OAAO,UAC1F;AACI,wBAAsB,KAAK,KAAK,EAAE;AAElC,QAAM,YAAY,iBAAiB,IAAI,SAAS,QAAQ;AACxD,QAAM,UAAU,SAAS;AAEzB,QAAMI,MAAK,cAAc,QAAQ;AACjC,QAAMC,MAAK,cAAc,QAAQ;AAEjC,QAAM,QAAQ,YAAY,MAAMA,KAAID,GAAE,CAAC;AAEvC,QAAM,cAAc,IAAI,qBAAqB;AAC7C,cAAY,QAAQ,MAAM,MAAM;AAEhC,QAAM,YAAY;AAClB,QAAM,QAAQ,YAAY,MAAMA,KAAI,cAAc,MAAM,CAAC;AACzD,cAAY,UAAU,YAAY,KAAK;AACvC,cAAY,UAAU,QAAQ,OAAO,KAAK,KAAK;AAE/C,QAAM,QAAQ,YAAY,MAAM,cAAc,QAAQC,GAAE,CAAC;AACzD,cAAY,UAAU,YAAY,KAAK;AACvC,cAAY,UAAU,QAAQ,OAAO,KAAK,KAAK;AAE/C,QAAM,UAAU,YAAY,KAAK;AACjC,QAAM,UAAU,MAAM,SAAS,MAAM,WAAWD,GAAE,CAAC,IAAI;AACvD,MAAI,UAAU;AACd,MAAI,UAAU;AAEd,MAAI,YAAY,SAChB;AACI,cAAU,MAAM,YAAY,SAAS,MAAM,WAAWA,GAAE,CAAC,IAAI;AAAA,EACjE;AAEA,MAAI,YAAY,SAChB;AACI,cAAU,MAAM,YAAY,SAAS,MAAM,WAAWC,GAAE,CAAC,IAAI;AAAA,EACjE;AAEA,MAAI,WAAW,WAAW,SAC1B;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAEA,QAAM,QAAQ,SAAS;AACvB,QAAM,WAAW,CAAC;AAClB,QAAM,UAAU,CAAC;AAEjB,WAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,aAAS,CAAC,IAAI,iBAAiB,IAAI,SAAS,SAAS,CAAC,CAAC;AACvD,YAAQ,CAAC,IAAI,eAAe,GAAG,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,EACzD;AAEA,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,YAAY,CAAE,cAAc,QAAQ,QAAQ,cAAc,QAAQ,MAAO,GAAG,GAAG,CAAG;AACjG,QAAM,SAAS,YAAY,UAAU,OAAO,CAAG;AAC/C,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,WAAW;AAEjB,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,MAAI,OAAO,WAAW,UAAU,wBAChC;AACI,WAAO,SAAS,MAAM;AAAA,EAC1B;AAEA,QAAM,KAAK,YAAY,UAAU,YAAY,UAAU;AACvD,QAAM,KAAK,YAAY,UAAU,YAAY,UAAU;AAEvD,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AAErB,MAAI,WAAW,SAAS,OAAO,WAAW,MAAM,eAChD;AACI,QAAI,MAAM,SAAS,GACnB;AACI,YAAM,KAAK,OAAO;AAClB,YAAM,KAAK,OAAO;AAElB,YAAM,SAAS,YAAY,MAAM,IAAI,EAAE,CAAC;AAExC,YAAM,OAAO,iBAAiB,aAAa,MAAM;AAEjD,UAAI,QAAQ,aAAa,eACzB;AACI,eAAO,SAAS,MAAM;AAAA,MAC1B;AAEA,UAAI,QAAQ,aAAa,gBACzB;AAEI,iBAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AACzD,iBAAS,UAAU,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO;AAGzD,cAAM,KAAK,IAAI,gBAAgB;AAG/B,WAAG,WAAW,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE,IAAI,GAAG;AAC5C,WAAG,WAAW,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE,IAAI,GAAG;AAG5C,WAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAC7C,WAAG,WAAW,GAAG,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE;AAG7C,WAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,WAAG,SAAS,IAAI,EAAE,IAAI,GAAG;AACzB,WAAG,aAAa,OAAO,WAAW;AAClC,WAAG,KAAK,WAAW,MAAM,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;AACnD,iBAAS,OAAO,CAAC,IAAI;AACrB,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACX;AAEA,sBAAgB,MAAM,OAAO,CAAC;AAAA,IAClC,OAEA;AACI,cAAQ,OAAO,MAAM,SAAS,CAAC;AAE/B,YAAM,MAAM,MAAM,OAAO,CAAC;AAC1B,YAAM,MAAM,MAAM,OAAO,CAAC;AAC1B,UAAIC,OAAM,MAAM,OAAO,CAAC;AACxB,UAAIC,OAAM,MAAM,OAAO,CAAC;AAExB,UAAI,OAAO,KACX;AACI,gBAAQ,OAAOD,QAAOC,IAAG;AAEzB,YAAI,UAAU,MAAM,OAAO,QAAQ,OAAO,MAAM;AAChD,YAAI,OAAO,MAAM,SAAS,QAAQD,IAAG,CAAC;AACtC,YAAI,OAAO,MAAM,SAAS,QAAQC,IAAG,CAAC;AACtC,cAAM,KAAK,OAAO,OAAOD,OAAMC;AAE/B,kBAAU,QAAQ,EAAE;AAEpB,cAAM,OAAO,iBAAiB,aAAa,MAAM,OAAO,CAAC;AAEzD,YAAI,QAAQ,aAAa,eACzB;AACI,iBAAO,SAAS,MAAM;AAAA,QAC1B;AAEA,YAAI,QAAQ,aAAa,gBACzB;AACI,UAAAD,OAAM;AACN,UAAAC,OAAM,KAAK,QAAQ,IAAI,KAAK,IAAI;AAEhC,gBAAMC,MAAK,SAASF,IAAG;AACvB,gBAAMG,MAAK,SAASF,IAAG;AAEvB,iBAAO,MAAM,SAAS,MAAMH,KAAII,GAAE,CAAC;AACnC,iBAAO,MAAM,SAAS,MAAMH,KAAIG,GAAE,CAAC;AAEnC,cAAI,OAAO,MACX;AACI,gBAAI,MAAM,IAAI,OAAO,IAAI,MAAM,SAAS,OAAO,GAC/C;AACI,qBAAO,SAAS,MAAM;AAAA,YAC1B;AAAA,UACJ,OAEA;AACI,gBAAI,MAAM,IAAI,OAAO,IAAI,MAAM,SAAS,OAAO,GAC/C;AACI,qBAAO,SAAS,MAAM;AAAA,YAC1B;AAAA,UACJ;AAEA,yBAAeA,KAAIC,KAAIL,KAAIC,KAAI,SAAS,SAAS,GAAK,WAAWC,MAAK,CAAC,GAAG,WAAWC,MAAK,CAAC,GAAG,QAAQ;AAGtG,mBAAS,UAAU,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,QAAQ;AAC7D,mBAAS,UAAU,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,QAAQ;AAG7D,mBAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,mBAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGnG,mBAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,mBAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,gBAAMG,OAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAG9B,mBAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAChE,mBAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAGhE,mBAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAChE,mBAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAGhE,mBAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,mBAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGzD,mBAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,mBAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAEzD,iBAAO;AAAA,QACX;AAEA,yBAAiB;AAAA,MACrB,OAEA;AACI,cAAM,OAAO,MAAM,SAAS,MAAM,SAASJ,IAAG,GAAGF,GAAE,CAAC;AACpD,cAAM,OAAO,MAAM,SAAS,MAAM,SAASG,IAAG,GAAGF,GAAE,CAAC;AACpD,wBAAgB,OAAO,OAAOC,OAAMC;AAAA,MACxC;AAAA,IACJ;AAAA,EACJ,OAEA;AAEI,QAAI,iBAAiB,OAAO;AAE5B,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,IAAI,MAAM,SAAS,MAAM,SAAS,CAAC,GAAGH,GAAE,CAAC;AAE/C,UAAI,IAAI,gBACR;AACI,yBAAiB;AACjB,wBAAgB;AAAA,MACpB;AAAA,IACJ;AAGA,QAAI,YAAY,SAChB;AACI,UAAI,KAAK,OAAO;AAEhB,eAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,cAAM,IAAI,MAAM,YAAY,SAAS,MAAM,SAAS,CAAC,GAAGA,GAAE,CAAC;AAE3D,YAAI,IAAI,IACR;AACI,eAAK;AAAA,QACT;AAAA,MACJ;AAEA,UAAI,KAAK,gBACT;AACI,yBAAiB;AACjB,wBAAgB;AAAA,MACpB;AAAA,IACJ;AAEA,QAAI,YAAY,SAChB;AACI,UAAI,KAAK,OAAO;AAEhB,eAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,cAAM,IAAI,MAAM,YAAY,SAAS,MAAM,SAAS,CAAC,GAAGC,GAAE,CAAC;AAE3D,YAAI,IAAI,IACR;AACI,eAAK;AAAA,QACT;AAAA,MACJ;AAEA,UAAI,KAAK,gBACT;AACI,yBAAiB;AACjB,wBAAgB;AAAA,MACpB;AAAA,IACJ;AAGA,QAAI,oBAAoB,CAAC,OAAO;AAChC,QAAI,iBAAiB;AAErB,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,IAAI,QAAQ,CAAC;AAEnB,YAAM,OAAO,iBAAiB,aAAa,MAAM,CAAC,CAAC;AAEnD,UAAI,QAAQ,aAAa,gBACzB;AACI;AAAA,MACJ;AAEA,YAAMM,KAAI,SAAS,CAAC;AACpB,YAAM,IAAI,KAAK,IAAI,MAAM,GAAG,MAAMN,KAAIM,EAAC,CAAC,GAAG,MAAM,GAAG,MAAMP,KAAIO,EAAC,CAAC,CAAC;AAEjE,UAAI,IAAI,mBACR;AACI,4BAAoB;AACpB,yBAAiB;AAAA,MACrB;AAAA,IACJ;AAEA,QAAI,oBAAoB,gBACxB;AACI,YAAM,MAAM;AACZ,YAAM,MAAM,MAAM,QAAQ,IAAI,MAAM,IAAI;AACxC,YAAM,KAAK,SAAS,GAAG;AACvB,YAAM,KAAK,SAAS,GAAG;AAEvB,YAAM,IAAI,QAAQ,GAAG;AAErB,YAAM,OAAO,MAAM,GAAG,MAAMP,KAAI,EAAE,CAAC;AACnC,YAAM,OAAO,MAAM,GAAG,MAAMC,KAAI,EAAE,CAAC;AAEnC,UAAI,OAAO,MACX;AACI,YAAI,MAAM,IAAI,CAAC,IAAI,MAAM,SAAS,CAAC,GACnC;AACI,iBAAO,SAAS,MAAM;AAAA,QAC1B;AAAA,MACJ,OAEA;AACI,YAAI,MAAM,IAAI,CAAC,IAAI,MAAM,SAAS,CAAC,GACnC;AACI,iBAAO,SAAS,MAAM,CAAC;AAAA,QAC3B;AAAA,MACJ;AAEA,qBAAe,IAAI,IAAID,KAAIC,KAAI,QAAQ,GAAG,GAAG,SAAS,GAAK,WAAW,KAAK,CAAC,GAAG,WAAW,KAAK,CAAC,GAAG,QAAQ;AAG3G,eAAS,UAAU,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,EAAE;AACvE,eAAS,UAAU,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,EAAE;AAGvE,eAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,eAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGnG,eAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,eAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,YAAMK,OAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAG9B,eAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAChE,eAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAGhE,eAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAChE,eAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAWA,KAAI;AAGhE,eAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,eAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGzD,eAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,eAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAEzD,aAAO;AAAA,IACX;AAEA,QAAI,iBAAiB,IACrB;AACI,aAAO,SAAS,MAAM;AAAA,IAC1B;AAAA,EACJ;AAEA,UAAQ,OAAO,kBAAkB,MAAM,iBAAiB,EAAE;AAE1D,MAAI,IAAI;AACR,MAAI,KAAK;AAET,MAAI,kBAAkB,IACtB;AACI,UAAM;AACN,UAAM,MAAM,QAAQ,IAAI,MAAM,IAAI;AAClC,SAAK,SAAS,GAAG;AACjB,SAAK,SAAS,GAAG;AAAA,EACrB,OAEA;AACI,UAAM,KAAK;AACX,UAAM,KAAK,KAAK,IAAI,KAAK,IAAI,QAAQ;AACrC,UAAM,KAAK,MAAM,SAAS,QAAQ,EAAE,CAAC;AACrC,UAAM,KAAK,MAAM,SAAS,QAAQ,EAAE,CAAC;AAErC,QAAI,KAAK,IACT;AACI,YAAM;AACN,YAAM;AACN,WAAK,SAAS,GAAG;AACjB,WAAK,SAAS,GAAG;AAAA,IACrB,OAEA;AACI,YAAM;AACN,YAAM,KAAK,QAAQ,IAAI,KAAK,IAAI;AAChC,WAAK,SAAS,GAAG;AACjB,WAAK,SAAS,GAAG;AAAA,IACrB;AAAA,EACJ;AAEA,iBAAeN,KAAIC,KAAI,IAAI,IAAI,SAAS,GAAK,SAAS,WAAW,GAAG,GAAG,GAAG,WAAW,GAAG,GAAG,GAAG,QAAQ;AAGtG,WAAS,UAAU,IAAI,EAAE,IAAI,SAAS,UAAU,IAAI,EAAE,IAAI,SAAS;AACnE,WAAS,UAAU,IAAI,EAAE,IAAI,SAAS,UAAU,IAAI,EAAE,IAAI,SAAS;AAGnE,WAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,WAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGnG,WAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,WAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACnG,QAAM,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAG9B,WAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI;AAChE,WAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI;AAGhE,WAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI;AAChE,WAAS,OAAO,CAAC,EAAE,WAAW,SAAS,OAAO,CAAC,EAAE,WAAW,IAAI;AAGhE,WAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,WAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAGzD,WAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AACzD,WAAS,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,IAAI,SAAS,OAAO,CAAC,EAAE;AAEzD,SAAO;AACX;;;ACz/DO,IAAM,iBAAiB;AAAA,EAC1B,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,+BAA+B;AACnC;AAEO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,EACnB;AACJ;AAEO,IAAM,YAAN,MACP;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,QAAQ,CAAE,IAAI,cAAc,GAAG,IAAI,cAAc,CAAE;AACxD,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AACJ;AAEO,IAAM,eAAN,MACP;AAAA,EACI,YAAY,WAAW,IAAI,WAAW,GACtC;AAEI,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,QAAQ,IAAI,gBAAgB;AAAA,EACrC;AAAA,EAEA,IAAI,KACJ;AACI,SAAK,YAAY,IAAI;AACrB,SAAK,WAAW,IAAI;AACpB,SAAK,WAAW,IAAI;AACpB,SAAK,gBAAgB,IAAI;AACzB,SAAK,gBAAgB,IAAI;AACzB,SAAK,WAAW,IAAI;AACpB,SAAK,WAAW,IAAI;AACpB,SAAK,WAAW,IAAI;AACpB,SAAK,QAAQ,IAAI;AACjB,SAAK,WAAW,IAAI;AACpB,SAAK,QAAQ,IAAI;AACjB,QAAI,SAAS,OAAO,KAAK,QAAQ;AACjC,SAAK,WAAW,IAAI;AACpB,SAAK,cAAc,IAAI;AACvB,SAAK,eAAe,IAAI;AACxB,SAAK,WAAW,IAAI;AACpB,SAAK,QAAQ,IAAI,MAAM,MAAM;AAAA,EACjC;AACJ;AAIA,SAAS,cAAc,WAAW,WAClC;AACI,SAAO,KAAK,KAAK,YAAY,SAAS;AAC1C;AAIA,SAAS,iBAAiB,cAAc,cACxC;AACI,SAAO,KAAK,IAAI,cAAc,YAAY;AAC9C;AAQA,IAAM,oBAAN,MACA;AAAA,EACI,YAAY,MAAM,MAAM,UAAU,OAClC;AACI,SAAK,MAAM;AACX,SAAK,UAAU;AAAA,EACnB;AACJ;AAEA,IAAM,cAAc,MAAM,YAAY,iBAAiB,EAAE,KAAK,EAAE;AAAA,EAAI,MAChE,MAAM,YAAY,iBAAiB,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,kBAAkB,CAAC;AACjF;AAEA,IAAI,gBAAgB;AAEb,SAAS,iBAAiB,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAClE;AACI,SAAO,iBAAiB,OAAO,QAAQ,KAAK,OAAO,QAAQ,KAAK,QAAQ;AAC5E;AAEO,SAAS,2BAA2B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC5E;AACI,SAAO,0BAA0B,OAAO,SAAS,KAAK,OAAO,QAAQ,KAAK,QAAQ;AACtF;AAEO,SAAS,kBAAkB,QAAQ,KAAK,QAAQ,KAAK,OAAO,UACnE;AACI,SAAO,kBAAkB,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,QAAQ;AAC/E;AAEO,SAAS,2BAA2B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC5E;AACI,SAAO,0BAA0B,OAAO,SAAS,KAAK,OAAO,QAAQ,KAAK,QAAQ;AACtF;AAEO,SAAS,4BAA4B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC7E;AACI,SAAO,2BAA2B,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,QAAQ;AACxF;AAEO,SAAS,kBAAkB,QAAQ,KAAK,QAAQ,KAAK,OAAO,UACnE;AACI,SAAO,kBAAkB,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,QAAQ;AAC/E;AAEO,SAAS,2BAA2B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC5E;AACI,SAAO,0BAA0B,OAAO,SAAS,KAAK,OAAO,QAAQ,KAAK,QAAQ;AACtF;AAEO,SAAS,4BAA4B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC7E;AACI,SAAO,2BAA2B,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,QAAQ;AACxF;AAEO,SAAS,4BAA4B,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAC7E;AACI,SAAO,2BAA2B,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,QAAQ;AACxF;AAEO,SAAS,gCAAgC,QAAQ,KAAK,QAAQ,KAAK,OAAO,UACjF;AACI,SAAO,+BAA+B,OAAO,cAAc,KAAK,OAAO,QAAQ,KAAK,QAAQ;AAChG;AAEO,SAAS,iCAAiC,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAClF;AACI,SAAO,gCAAgC,OAAO,cAAc,KAAK,OAAO,SAAS,KAAK,OAAO,QAAQ;AACzG;AAEO,SAAS,iCAAiC,QAAQ,KAAK,QAAQ,KAAK,OAAO,UAClF;AACI,SAAO,gCAAgC,OAAO,cAAc,KAAK,OAAO,SAAS,KAAK,OAAO,QAAQ;AACzG;AAEO,SAAS,UAAU,KAAK,OAAO,OACtC;AACI,UAAQ,OAAO,KAAK,SAAS,QAAQ,YAAY,iBAAiB;AAClE,UAAQ,OAAO,KAAK,SAAS,QAAQ,YAAY,iBAAiB;AAClE,cAAY,KAAK,EAAE,KAAK,EAAE,MAAM;AAChC,cAAY,KAAK,EAAE,KAAK,EAAE,UAAU;AAEpC,MAAK,SAAS,OACd;AACI,gBAAY,KAAK,EAAE,KAAK,EAAE,MAAM;AAChC,gBAAY,KAAK,EAAE,KAAK,EAAE,UAAU;AAAA,EACxC;AACJ;AAGO,SAAS,+BAChB;AACI,MAAI,kBAAkB,OACtB;AACI,cAAU,kBAAkB,YAAY,gBAAgB,YAAY,cAAc;AAClF,cAAU,4BAA4B,YAAY,iBAAiB,YAAY,cAAc;AAC7F,cAAU,mBAAmB,YAAY,iBAAiB,YAAY,eAAe;AACrF,cAAU,4BAA4B,YAAY,iBAAiB,YAAY,cAAc;AAC7F,cAAU,6BAA6B,YAAY,iBAAiB,YAAY,eAAe;AAC/F,cAAU,mBAAmB,YAAY,iBAAiB,YAAY,eAAe;AACrF,cAAU,4BAA4B,YAAY,iBAAiB,YAAY,cAAc;AAC7F,cAAU,6BAA6B,YAAY,iBAAiB,YAAY,eAAe;AAC/F,cAAU,6BAA6B,YAAY,iBAAiB,YAAY,eAAe;AAC/F,cAAU,iCAAiC,YAAY,sBAAsB,YAAY,cAAc;AACvG,cAAU,kCAAkC,YAAY,sBAAsB,YAAY,eAAe;AACzG,cAAU,kCAAkC,YAAY,sBAAsB,YAAY,eAAe;AACzG,oBAAgB;AAAA,EACpB;AACJ;AAEO,SAAS,gBAAgB,OAAO,QAAQ,QAC/C;AACI,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,OAAO;AAErB,MAAI,YAAY,KAAK,EAAE,KAAK,EAAE,QAAQ,MACtC;AAEI;AAAA,EACJ;AAEA,MAAI,YAAY,KAAK,EAAE,KAAK,EAAE,YAAY,OAC1C;AAEI,oBAAgB,OAAO,QAAQ,MAAM;AAErC;AAAA,EACJ;AAEA,QAAM,QAAQ,UAAU,OAAO,OAAO,MAAM;AAC5C,QAAM,QAAQ,UAAU,OAAO,OAAO,MAAM;AAE5C,MAAI;AAEJ,MAAI,MAAM,aAAa,UAAU,eAAe,MAAM,aAAa,UAAU,aAC7E;AACI,eAAW,UAAU;AAAA,EACzB,OAEA;AAII,eAAW,UAAU;AAAA,EACzB;AAEA,QAAM,MAAM,MAAM,eAAe,QAAQ;AAGzC,QAAM,YAAY,UAAU,MAAM,aAAa;AAG/C,SAAO,MAAM,aAAa,UAAU,WACpC;AACI,UAAM,aAAa,KAAK,IAAI,UAAU,CAAC;AAAA,EAC3C;AAEA,QAAM,WAAW,OAAO;AACxB,QAAM,WAAW,OAAO;AAExB,QAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,UAAQ,YAAY;AACpB,UAAQ,WAAW;AACnB,UAAQ,aAAa;AACrB,UAAQ,aAAa,IAAI,SAAS;AAClC,UAAQ,WAAW;AACnB,UAAQ,aAAa;AACrB,UAAQ,aAAa;AACrB,UAAQ,WAAW;AACnB,UAAQ,WAAW;AACnB,UAAQ,WAAW;AACnB,UAAQ,QAAQ;AAEhB,MAAI,OAAO,YAAY,OAAO,UAC9B;AACI,YAAQ,SAAS,eAAe;AAAA,EACpC;AAEA,MAAI,OAAO,sBAAsB,OAAO,oBACxC;AACI,YAAQ,SAAS,eAAe;AAAA,EACpC;AAEA,MAAI,OAAO,uBAAuB,OAAO,qBACzC;AACI,YAAQ,SAAS,eAAe;AAAA,EACpC;AAGA;AACI,YAAQ,MAAM,CAAC,EAAE,SAAS,OAAO;AACjC,YAAQ,MAAM,CAAC,EAAE,UAAU;AAC3B,YAAQ,MAAM,CAAC,EAAE,UAAU,MAAM;AAEjC,UAAM,OAAQ,aAAa,IAAK;AAChC,UAAM,iBAAiB,MAAM;AAE7B,QAAI,mBAAmB,eACvB;AACI,YAAM,cAAc,MAAM,aAAa,kBAAkB,CAAC;AAC1D,kBAAY,MAAM,iBAAiB,CAAC,EAAE,UAAU;AAAA,IACpD;AACA,UAAM,iBAAiB;AACvB,UAAM,gBAAgB;AAAA,EAC1B;AAGA;AACI,YAAQ,MAAM,CAAC,EAAE,SAAS,OAAO;AACjC,YAAQ,MAAM,CAAC,EAAE,UAAU;AAC3B,YAAQ,MAAM,CAAC,EAAE,UAAU,MAAM;AAEjC,UAAM,OAAQ,aAAa,IAAK;AAChC,UAAM,iBAAiB,MAAM;AAE7B,QAAI,MAAM,mBAAmB,eAC7B;AACI,YAAM,cAAc,MAAM,aAAa,kBAAkB,CAAC;AAC1D,kBAAY,MAAM,iBAAiB,CAAC,EAAE,UAAU;AAAA,IACpD;AACA,UAAM,iBAAiB;AACvB,UAAM,gBAAgB;AAAA,EAC1B;AAGA,QAAM,UAAU,kBAAkB,UAAU,QAAQ;AACpD,WAAS,MAAM,WAAW,SAAS,OAAO;AAI1C,QAAM,aAAa,aAAa,IAAI,QAAQ;AAC5C,aAAW,YAAY;AAGvB,aAAW,WAAW,OAAO;AAC7B,aAAW,WAAW,OAAO;AAC7B,UAAQ,OAAO,WAAW,aAAa,WAAW,QAAQ;AAI1D,aAAW,gBAAgB;AAC3B,aAAW,gBAAgB;AAC3B,aAAW,WAAW;AACtB,aAAW,QAAQ;AACnB,aAAW,WAAW;AACtB,aAAW,QAAQ;AACnB,aAAW,WAAW;AACtB,aAAW,WAAW;AAItB,aAAW,WAAW,cAAc,OAAO,UAAU,OAAO,QAAQ;AACpE,aAAW,cAAc,iBAAiB,OAAO,aAAa,OAAO,WAAW;AAChF,aAAW,eAAe;AAC1B,aAAW,WAAW;AAEtB,MAAI,OAAO,wBAAwB,OAAO,sBAC1C;AACI,eAAW,YAAY,kBAAkB;AAAA,EAC7C;AACJ;AAEO,SAAS,iBAAiB,OAAO,SAAS,YACjD;AAEI,QAAM,UAAU,kBAAkB,QAAQ,UAAU,QAAQ,QAAQ;AACpE,cAAY,MAAM,WAAW,SAAS,OAAO;AAE7C,QAAM,QAAQ,QAAQ,MAAM,CAAC;AAC7B,QAAM,QAAQ,QAAQ,MAAM,CAAC;AAE7B,QAAM,UAAU,MAAM;AACtB,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ,UAAU,OAAO,OAAO;AACtC,QAAM,QAAQ,UAAU,OAAO,OAAO;AAEtC,QAAM,QAAQ,QAAQ;AAEtB,OAAK,SAAS,eAAe,yBAAyB,eAAe,kCAAkC,MAAM,SAAS,eAAe,gCAAgC,eAAe,kCAAkC,GACtN;AACI,UAAM,UAAU,MAAM;AACtB,UAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAChD,UAAM,SAAS,MAAM,WAAW,QAAQ,QAAQ;AAChD,UAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,SAAS,OAAO,QAAQ;AACtE,UAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,SAAS,OAAO,QAAQ;AAGtE,SAAK,QAAQ,eAAe,2BAA2B,MAAM,QAAQ,eAAe,kCAAkC,GACtH;AACI,cAAQ,QAAU,QAAQ,eAAe,yBAA0B,CAAE;AACrE,YAAM,QAAQ,IAAI,uBAAuB,UAAU,QAAQ;AAC3D,YAAM,gBAAgB,KAAK,KAAK;AAAA,IACpC;AAEA,SAAK,QAAQ,eAAe,iCAAiC,MAAM,QAAQ,eAAe,iCAAiC,GAC3H;AACI,cAAQ,QAAU,QAAQ,eAAe,yBAA0B,CAAE;AACrE,cAAQ,OAAQ,OAAO,YAAY,QAAQ,OAAO,YAAY,IAAK;AACnE,cAAQ,OAAQ,OAAO,YAAY,OAAO,QAAS;AAEnD,YAAM,QAAQ,IAAI,sBAAsB;AAExC,UAAI,OAAO,UACX;AACI,cAAM,gBAAgB;AACtB,cAAM,iBAAiB;AAAA,MAC3B,OAEA;AACI,cAAM,gBAAgB;AACtB,cAAM,iBAAiB;AAAA,MAC3B;AAEA,YAAM,oBAAoB,KAAK,KAAK;AAAA,IACxC;AAAA,EACJ;AAGA,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,cAAc,MAAM,aAAa,MAAM,WAAW,CAAC;AACzD,UAAM,WAAW,YAAY,MAAM,MAAM,UAAU,CAAC;AACpD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,cAAc,MAAM,aAAa,MAAM,WAAW,CAAC;AACzD,UAAM,WAAW,YAAY,MAAM,MAAM,UAAU,CAAC;AACpD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,QAAM,YAAY,QAAQ;AAE1B,QAAM,WAAY,aAAa,IAAK;AAEpC,MAAI,MAAM,mBAAmB,UAC7B;AACI,UAAM,iBAAiB,MAAM;AAAA,EACjC;AAEA,QAAM,gBAAgB;AAGtB,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,cAAc,MAAM,aAAa,MAAM,WAAW,CAAC;AACzD,UAAM,WAAW,YAAY,MAAM,MAAM,UAAU,CAAC;AACpD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,MAAI,MAAM,YAAY,eACtB;AACI,UAAM,cAAc,MAAM,aAAa,MAAM,WAAW,CAAC;AACzD,UAAM,WAAW,YAAY,MAAM,MAAM,UAAU,CAAC;AACpD,aAAS,UAAU,MAAM;AAAA,EAC7B;AAEA,QAAM,WAAY,aAAa,IAAK;AAEpC,MAAI,MAAM,mBAAmB,UAC7B;AACI,UAAM,iBAAiB,MAAM;AAAA,EACjC;AAEA,QAAM,gBAAgB;AAGtB,MAAI,QAAQ,aAAa,eACzB;AACI,oBAAgB,OAAO,OAAO;AAAA,EAClC;AAEA,MAAI,QAAQ,eAAe,eAC3B;AAEI,YAAQ,OAAO,QAAQ,YAAY,UAAU,WAAW;AACxD,6BAAyB,OAAO,SAAS,SAAS,QAAQ,YAAY,QAAQ,UAAU;AAAA,EAC5F,OAEA;AAEI,YAAQ,OAAO,QAAQ,YAAY,UAAU,gBACxC,QAAQ,QAAQ,eAAe,2BAA2B,MAC1D,QAAQ,QAAQ,eAAe,yBAAyB,CAAC;AAC9D,UAAM,MAAM,MAAM,eAAe,QAAQ,QAAQ;AACjD,UAAM,aAAa,gBAAgB,IAAI,UAAU,QAAQ,UAAU;AAEnE,QAAI,eAAe,eACnB;AACI,YAAM,eAAe,IAAI,SAAS,KAAK,QAAQ,UAAU;AACzD,YAAM,aAAa,aAAa,SAAS,EAAE,aAAa,QAAQ;AAAA,IACpE;AAAA,EACJ;AAEA,UAAQ,YAAY;AACpB,UAAQ,WAAW;AACnB,UAAQ,aAAa;AACrB,UAAQ,aAAa;AAErB,WAAS,MAAM,eAAe,SAAS;AAEvC,MAAI,YACJ;AACI,eAAW,OAAO,KAAK;AACvB,eAAW,OAAO,KAAK;AAAA,EAC3B;AACJ;AAEO,SAAS,gBAAgB,OAAO,SACvC;AACI,MAAI,QAAQ,aAAa,UAAU,eAAe,QAAQ,eAAe,eACzE;AAEI,YAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,aAAa,kBAAkB;AACjF,UAAM,QAAQ,MAAM,gBAAgB,OAAO,QAAQ,UAAU;AAC7D,YAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,aAAa,MAAM,SAAS,KAAK;AAEnF,UAAM,MAAM,MAAM,SAAS,KAAK,QAAQ,UAAU;AAIlD,WAAO;AAAA,EACX;AAGA,QAAM,MAAM,MAAM,eAAe,QAAQ,QAAQ;AACjD,UAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,cAAc,IAAI,SAAS,KAAK;AAElF,SAAO,IAAI,SAAS,KAAK,QAAQ,UAAU;AAC/C;AAEO,SAAS,sBAAsB,SAAS,SAC/C;AACI,MAAI,QAAQ,eAAe,QAAQ,cAAc,QAAQ,eAAe,GACxE;AACI,WAAO,QAAQ,aAAa;AAAA,EAChC;AAEA,QAAM,WAAW,QAAQ,WAAW,QAAQ,kBAAkB,MAAM,QAAQ,eAAe,QAAQ,cAAc;AAEjH,SAAO;AACX;AAEA,SAAS,mBAAmB,QAAQ,KAAK,QAAQ,KAAK,OACtD;AACI,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,yBAAyB,MAAM;AAC9C,QAAM,SAAS,yBAAyB,MAAM;AAC9C,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,WAAW;AAEjB,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,SAAO,OAAO,WAAW,KAAO;AACpC;AAEA,IAAM,cAAc,IAAI,WAAW;AAE5B,SAAS,gBAAgB,OAAO,YAAY,QAAQ,YAAYO,gBAAe,QAAQ,YAAYC,gBAC1G;AACI,MAAI;AAGJ,MAAI,OAAO,YAAY,OAAO,UAC9B;AAEI,eAAW,mBAAmB,QAAQ,YAAY,QAAQ,YAAY,WAAW,KAAK;AAAA,EAC1F,OAEA;AAEI,eAAW,SAAS,OAAO,WAAW;AAGtC,UAAM,MAAM,YAAY,OAAO,IAAI,EAAE,OAAO,IAAI,EAAE;AAGlD,QAAI,QAAQ,YAAY,QAAQ,YAAY,WAAW,OAAO,WAAW,QAAQ;AAEjF,UAAM,aAAa,WAAW,SAAS;AACvC,eAAW,aAAa;AAExB,QAAK,YAAY,MAAM,gBAAiB,WAAW,WAAW,kBAAkB,+BAAgC,GAChH;AACI,YAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,MAAM,SAAS,OAAO,QAAQ;AAC5E,YAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,MAAM,SAAS,OAAO,QAAQ;AAG5E,iBAAW,MAAM,YAAa,UAAU,UAAU,WAAW,UAAU,MAAM,eAAgB;AAE7F,UAAK,YAAY,OACjB;AAEI,mBAAW,SAAS,aAAa;AAAA,MACrC;AAAA,IACJ;AAEA,QAAI,aAAa,OAAO,mBAAmB,OAAO,kBAClD;AACI,iBAAW,YAAY,kBAAkB;AAAA,IAC7C,OAEA;AACI,iBAAW,YAAY,CAAC,kBAAkB;AAAA,IAC9C;AAIA,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,YAAM,MAAM,WAAW,SAAS,OAAO,CAAC;AAIxC,UAAI,YAAYD,eAAc;AAC9B,UAAI,YAAYA,eAAc;AAG9B,UAAI,YAAYC,eAAc;AAC9B,UAAI,YAAYA,eAAc;AAE9B,UAAI,gBAAgB;AACpB,UAAI,iBAAiB;AACrB,UAAI,mBAAmB;AACvB,UAAI,iBAAiB;AACrB,UAAI,YAAY;AAEhB,YAAM,MAAM,IAAI;AAEhB,eAAS,IAAI,GAAG,IAAI,YAAY,YAAY,IAAI,GAAG,EAAE,GACrD;AACI,cAAM,MAAM,YAAY,OAAO,CAAC;AAEhC,YAAI,IAAI,OAAO,KACf;AACI,cAAI,gBAAgB,IAAI;AACxB,cAAI,iBAAiB,IAAI;AACzB,cAAI,YAAY;AAEhB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,UACJ;AACI,eAAW,YAAY,kBAAkB;AAAA,EAC7C,OAEA;AACI,eAAW,YAAY,CAAC,kBAAkB;AAAA,EAC9C;AAEA,SAAO;AACX;AAEO,SAAS,kBAAkB,QAAQ,YAAY,QAAQ,YAAY,UAC1E;AACI,QAAM,MAAM,YAAY,OAAO,IAAI,EAAE,OAAO,IAAI,EAAE;AAClD,QAAM,QAAQ,IAAI,gBAAgB;AAElC,SAAO,IAAK,QAAQ,YAAY,QAAQ,YAAY,OAAO,QAAS;AACxE;;;AC1rBO,IAAM,oBAAoB;AAAA,EAC7B,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,4BAA4B;AAChC;;;ACyBA,IAAM,eAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ,IAAI,MAAM,WAAW,gBAAgB,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,cAAc,CAAC;AAGxF,SAAK,UAAU;AACf,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,mBAAmB;AACxB,SAAK,gBAAgB;AACrB,SAAK,UAAU;AAAA,EACnB;AACJ;AAGA,IAAM,gBAAgB,CAAC,QAAQ,MAAM;AACrC,IAAM,cAAc,CAAC,QAAQ,OAAO;AACpC,IAAM,eAAe,CAAC,IAAI,SAAU,MAAM,IAAK;AAM/C,SAAS,aAAa,IAAI,YAC1B;AAEI,MAAI,CAAC,SAAS,GAAG,SAAS,aAAa,CAAC,GACxC;AACI,OAAG,UAAU,KAAK,UAAU;AAAA,EAChC;AACJ;AAEA,SAAS,mBAAmB,IAC5B;AAEI,KAAG,UAAU,YAAY;AACzB,KAAG,YAAY,CAAC;AAChB,KAAG,cAAc;AACjB,KAAG,YAAY;AACf,KAAG,mBAAmB;AACtB,KAAG,gBAAgB;AACnB,KAAG,UAAU,YAAY;AAEzB,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,OAAG,MAAM,CAAC,IAAI,qBAAqB;AAAA,EACvC;AACJ;AAEA,SAAS,oBAAoB,IAC7B;AACI,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,0BAAsB,GAAG,MAAM,CAAC,CAAC;AAAA,EACrC;AAEA,eAAa,GAAG,OAAO;AACvB,KAAG,YAAY;AACf,eAAa,GAAG,OAAO;AAEvB,SAAO,KAAK,EAAE,EAAE,QAAQ,SAAO,OAAO,GAAG,GAAG,CAAC;AACjD;AAEA,SAAS,eAAe,IAAI,UAC5B;AACI,QAAM,QAAQ,YAAY,GAAG,SAAS,WAAW,CAAC;AAElD,MAAI,OACJ;AACI,UAAM,QAAQ,GAAG,UAAU;AAE3B,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,UAAI,GAAG,UAAU,CAAC,MAAM,UACxB;AAEI,WAAG,UAAU,CAAC,IAAI,GAAG,UAAU,QAAQ,CAAC;AACxC,WAAG,UAAU,IAAI;AAEjB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,SAAS,yBAAyB,IAAI,WAAW,MAAM,cAAc,YAAY,mBACjF;AACI,UAAQ,OAAO,KAAK,aAAa,YAAY,WAAW,gBAAgB;AACxE,QAAM,UAAU,0BAA0B,GAAG,MAAM,SAAS,GAAG,MAAM,cAAc,UAAU;AAC7F,QAAM,WAAW,aAAa,SAAS,SAAS;AAEhD,MAAI,cAAc,WAAW,iBAAiB,mBAC9C;AACI,iBAAa,IAAI,QAAQ;AAAA,EAC7B;AAEA,SAAO;AACX;AAEA,SAAS,0BAA0B,IAAI,UACvC;AACI,UAAQ,OAAO,GAAG,UAAU,WAAW,GAAG,QAAQ,IAAI;AACtD,iBAAe,IAAI,QAAQ;AAI3B,QAAM,YAAY,cAAc,QAAQ;AACxC,QAAM,UAAU,YAAY,QAAQ;AAEpC,UAAQ,OAAO,KAAK,aAAa,aAAa,WAAW,gBAAgB;AACzE,6BAA2B,GAAG,MAAM,SAAS,GAAG,OAAO;AAC3D;AAEA,SAAS,uBAAuB,IAAI,UAAU,MAC9C;AACI,QAAM,YAAY,cAAc,QAAQ;AACxC,QAAM,UAAU,YAAY,QAAQ;AAEpC,0BAAwB,GAAG,MAAM,SAAS,GAAG,SAAS,IAAI;AAC1D,eAAa,IAAI,QAAQ;AAC7B;AAEA,SAAS,0BAA0B,IAAI,UAAU,MACjD;AACI,UAAQ,OAAO,aAAa,aAAa;AACzC,QAAM,YAAY,cAAc,QAAQ;AACxC,QAAM,UAAU,YAAY,QAAQ;AAEpC,UAAQ,OAAO,cAAc,WAAW,aAAa;AAErD,6BAA2B,GAAG,MAAM,SAAS,GAAG,SAAS,IAAI;AAC7D,eAAa,IAAI,QAAQ;AAC7B;AAEA,IAAM,aAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,OAAO;AAAA,EAChB;AACJ;AAEA,IAAM,eAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,WAAW;AAAA,EACpB;AACJ;AAEA,IAAM,qBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ;AACb,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AAAA,EAC3B;AACJ;AAEO,SAAS,oBAAoB,SAAS,SAAS,SACtD;AACI,QAAM,eAAe;AACrB,QAAM,KAAK,aAAa,MAAM;AAE9B,QAAM,WAAW,aAAa,SAAS,aAAa,aAAa;AAEjE,MAAI,aAAa,aAAa,eAC9B;AACI,WAAO;AAAA,EACX;AAEA,MAAI,aAAa,kBAAkB,WAAW,eAC9C;AACI,QAAI,WAAW,aAAa,iBAAiB,cAAc,GAAG,SAAS,WAAW,CAAC,GACnF;AACI,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,QAAM,UAAU,kBAAkB,SAAS,aAAa,eAAe;AAEvE,MAAI,cAAc,GAAG,SAAS,OAAO,GACrC;AACI,WAAO;AAAA,EACX;AAEA,MAAI,UAAU;AAEd,MAAI,WAAW,aAAa,eAC5B;AACI,eAAW;AACX,eAAW,aAAa;AAAA,EAC5B,OAEA;AACI,eAAW,aAAa;AACxB,eAAW;AAAA,EACf;AAEA,QAAM,QAAQ,aAAa;AAK3B,QAAM,SAAS,MAAM,WAAW,QAAQ;AACxC,QAAM,SAAS,MAAM,WAAW,QAAQ;AAExC,QAAM,UAAU,OAAO;AACvB,QAAM,UAAU,OAAO;AAEvB,MAAI,YAAY,SAChB;AACI,WAAO;AAAA,EACX;AAEA,MAAI,CAAC,sBAAsB,OAAO,QAAQ,OAAO,MAAM,GACvD;AACI,WAAO;AAAA,EACX;AAEA,MAAI,OAAO,YAAY,OAAO,UAC9B;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,OAAO,OAAO;AACtC,QAAM,QAAQ,UAAU,OAAO,OAAO;AAEtC,MAAI,CAAC,sBAAsB,OAAO,OAAO,KAAK,GAC9C;AACI,WAAO;AAAA,EACX;AAEA,QAAM,kBAAkB,aAAa,MAAM;AAE3C,MAAI,iBACJ;AACI,UAAM,MAAM,IAAI,UAAU,WAAW,GAAG,MAAM,SAAS,OAAO,QAAQ;AACtE,UAAM,MAAM,IAAI,UAAU,WAAW,GAAG,MAAM,SAAS,OAAO,QAAQ;AACtE,UAAM,gBAAgB,gBAAgB,KAAK,KAAK,aAAa,MAAM,mBAAmB;AAEtF,QAAI,CAAC,eACL;AACI,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,QAAM,YAAY,GAAG;AAErB,MAAI;AAEJ,MAAI,YAAY,GAAG,kBACnB;AACI,WAAO,GAAG,UAAU,SAAS;AAAA,EACjC,OAEA;AACI,WAAO,IAAI,WAAW;AAAA,EAC1B;AAEA,OAAK,cAAc;AACnB,OAAK,cAAc;AACnB,OAAK,OAAO,aAAa,WAAW;AACpC,eAAa,WAAW,WAAW;AAEnC,SAAO;AACX;AAEA,SAAS,wBAAwB,OACjC;AACI,QAAM,KAAK,MAAM;AACjB,QAAM,YAAY,GAAG,UAAU;AAE/B,MAAI,cAAc,GAAG;AAAE;AAAA,EAAQ;AAE/B,QAAM,QAAQ,MAAM;AACpB,KAAG,cAAc,oBAAoB,OAAO,WAAW,gBAAgB,MAAM,IAAI,aAAa,CAAC;AAE/F,kBAAgB,GAAG,WAAW,KAAK;AAEnC,QAAM,SAAS,MAAM;AAErB,aAAW,UAAU,GAAG,aACxB;AACI,aAAS,OAAO,OAAO,UAAU,MAAM,OAAO,KAAK,MACnD;AACI,sBAAgB,OAAO,OAAO,KAAK,WAAW,GAAG,OAAO,KAAK,WAAW,CAAC;AAAA,IAC7E;AAAA,EACJ;AAEA,KAAG,UAAU,SAAS;AACtB,aAAW,GAAG,OAAO;AACrB,kBAAgB,OAAO,GAAG,WAAW;AACrC,KAAG,cAAc;AAEjB,uBAAqB,KAAK;AAC9B;AAEA,SAAS,gBAAgB,YAAY,UAAU,OAC/C;AACI,QAAM,KAAK,MAAM;AACjB,QAAM,eAAe,IAAI,mBAAmB;AAC5C,eAAa,QAAQ;AAErB,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,WAAW,GAAG,UAAU,CAAC;AAE/B,QAAI,aAAa,eAAe;AAAE;AAAA,IAAU;AAE5C,UAAM,YAAY,cAAc,QAAQ;AACxC,UAAM,UAAU,YAAY,QAAQ;AACpC,iBAAa,gBAAgB;AAE7B,UAAM,WAAW,GAAG,MAAM,SAAS;AACnC,UAAM,UAAU,SAAS,MAAM,OAAO,EAAE;AACxC,iBAAa,kBAAkB,0BAA0B,UAAU,OAAO;AAE1E,UAAM,aAAa,GAAG,YAAY,CAAC;AACnC,eAAW,WAAW;AACtB,iBAAa,aAAa;AAE1B,QAAI,cAAc,WAAW,gBAC7B;AACI,0BAAoB,IAAI,SAAS,cAAc,WAAW,gBAAgB;AAC1E,0BAAoB,IAAI,SAAS,cAAc,WAAW,aAAa;AAAA,IAC3E;AAEA,iBAAa,gBAAgB,WAAW;AACxC,2BAAuB,GAAG,MAAM,WAAW,cAAc,GAAG,SAAS,YAAY;AAAA,EACrF;AACJ;AAEA,SAAS,oBAAoB,IAAI,SAAS,cAAc,UACxD;AACI,eAAa,gBAAgB;AAC7B,yBAAuB,GAAG,MAAM,QAAQ,GAAG,SAAS,YAAY;AACpE;AAeA,SAAS,0BAA0B,IACnC;AACI,wBAAsB,GAAG,MAAM,WAAW,cAAc,CAAC;AACzD,wBAAsB,GAAG,MAAM,WAAW,gBAAgB,CAAC;AAC/D;;;AC/UO,IAAM,gBAAgB;AAEtB,IAAM,YACb;AAAA,EACI,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,qBAAqB;AACzB;AAEO,IAAM,UAAN,MACP;AAAA,EACI,iBAAiB,IAAI,iBAAiB;AAAA,EACtC,aAAa,IAAI,aAAa;AAAA,EAC9B,kBAAkB,IAAI,kBAAkB;AAAA;AAAA,EAGxC,YAAY,CAAC;AAAA;AAAA,EAGb,iBAAiB,CAAC;AAAA;AAAA,EAGlB,aAAa,CAAC;AAAA;AAAA,EAGd,eAAe,CAAC;AAAA;AAAA,EAGhB,cAAc,CAAC;AAAA;AAAA;AAAA,EAIf,aAAa,CAAC;AAAA,EACd,aAAa,CAAC;AAAA,EACd,mBAAmB,CAAC;AAAA,EACpB,qBAAqB,CAAC;AAAA,EACtB,wBAAwB,CAAC;AAAA,EACzB,sBAAsB,CAAC;AAAA,EACvB,oBAAoB,CAAC;AAAA,EACrB,kBAAkB,CAAC;AAAA,EACnB,kBAAkB,CAAC;AAAA,EACnB,eAAe,IAAI,SAAS;AAAA,EAC5B,gBAAgB,IAAI,SAAS;AAAA,EAC7B,kBAAkB,IAAI,SAAS;AAAA,EAC/B,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,UAAU,IAAI,OAAO,GAAG,CAAC;AAAA,EACzB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,aAAa;AAAA,EACb,oBAAoB;AAAA,EACpB,WAAW;AAAA;AAAA,EAGX,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,UAAU,IAAI,UAAU;AAAA,EACxB,cAAc;AAAA,EACd,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,QAAQ;AACZ;AAEA,IAAM,sBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,cAAc;AAAA,EACvB;AACJ;AAEA,IAAM,sBAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,cAAc;AAAA,EACvB;AACJ;AAIO,IAAM,gBAAN,MACP;AAAA,EACI,cACA;AAEI,SAAK,qBAAqB,IAAI,SAAS;AAIvC,SAAK,oBAAoB,IAAI,SAAS;AAGtC,SAAK,oBAAoB,IAAI,SAAS;AAGtC,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AAAA,EACzB;AACJ;AAEO,SAAS,iBAAiB,IACjC;AACI,UAAQ,OAAO,KAAK,GAAG,UAAU,GAAG,UAAU,aAAa;AAC3D,QAAM,QAAQ,UAAU,GAAG,SAAS,CAAC;AACrC,UAAQ,OAAO,GAAG,WAAW,MAAM,UAAU,CAAC;AAC9C,UAAQ,OAAO,GAAG,aAAa,MAAM,QAAQ;AAE7C,SAAO;AACX;AAEO,SAAS,WAAW,OAC3B;AACI,UAAQ,OAAO,KAAK,SAAS,QAAQ,aAAa;AAClD,QAAM,QAAQ,UAAU,KAAK;AAC7B,UAAQ,OAAO,MAAM,YAAY,KAAK;AAEtC,SAAO;AACX;AAEO,SAAS,iBAAiB,OACjC;AACI,UAAQ,OAAO,KAAK,SAAS,QAAQ,aAAa;AAClD,QAAM,QAAQ,UAAU,KAAK;AAC7B,UAAQ,OAAO,MAAM,YAAY,KAAK;AAEtC,MAAI,MAAM,QACV;AACI,YAAQ,OAAO,KAAK;AAEpB,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAGA,IAAI,YAAY;AAWT,SAAS,qBAChB;AAEI,MAAI,aAAa,MACjB;AACI;AAAA,EACJ;AAEA,cAAY,CAAC;AAEb,WAAS,IAAI,GAAG,IAAI,eAAe,KACnC;AACI,cAAU,CAAC,IAAI,IAAI,QAAQ;AAC3B,cAAU,CAAC,EAAE,QAAQ;AAAA,EACzB;AACJ;AAkBO,SAAS,cAAc,KAC9B;AAGI,MAAI,UAAU;AAEd,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,EAAE,GACxC;AACI,QAAI,UAAU,CAAC,EAAE,UAAU,OAC3B;AACI,gBAAU;AAEV;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,YAAY,eAChB;AACI,WAAO,IAAI,UAAU,GAAG,CAAC;AAAA,EAC7B;AAEA,+BAA6B;AAE7B,QAAM,QAAQ,UAAU,OAAO;AAC/B,QAAM,WAAW,MAAM;AAEvB,QAAM,UAAU;AAChB,QAAM,WAAW;AACjB,QAAM,QAAQ;AAEd,QAAM,iBAAiB,uBAAuB;AAC9C,qBAAmB,MAAM,UAAU;AACnC,QAAM,kBAAkB,cAAc,MAAM,iBAAiB,EAAE;AAG/D,QAAM,aAAa,eAAe,MAAM;AACxC,QAAM,YAAY,CAAC;AACnB,QAAM,iBAAiB,CAAC;AAGxB,QAAM,kBAAkB,eAAe,WAAW;AAClD,MAAI;AAGJ,QAAM,IAAI,YAAY;AACtB,MAAI,WAAW,UAAU,MAAM,eAAe;AAC9C,QAAM,eAAe,KAAK,GAAG;AAC7B,UAAQ,OAAO,MAAM,eAAe,UAAU,YAAY,EAAE,aAAa,UAAU,YAAY;AAG/F,QAAM,IAAI,YAAY;AACtB,MAAI,WAAW,UAAU,MAAM,eAAe;AAC9C,QAAM,eAAe,KAAK,GAAG;AAC7B,UAAQ,OAAO,MAAM,eAAe,UAAU,cAAc,EAAE,aAAa,UAAU,cAAc;AAGnG,QAAM,IAAI,YAAY;AACtB,MAAI,WAAW,UAAU,MAAM,eAAe;AAC9C,QAAM,eAAe,KAAK,GAAG;AAC7B,UAAQ,OAAO,MAAM,eAAe,UAAU,WAAW,EAAE,aAAa,UAAU,WAAW;AAE7F,QAAM,cAAc,eAAe,SAAS;AAC5C,QAAM,aAAa,CAAC;AAEpB,QAAM,cAAc,eAAe,SAAS;AAC5C,QAAM,aAAa,CAAC;AAEpB,QAAM,gBAAgB,eAAe,WAAW;AAChD,QAAM,eAAe,CAAC;AAGtB,WAAS,IAAI,GAAG,IAAI,MAAM,KAC1B;AACI,UAAM,aAAa,KAAK,IAAI,UAAU,CAAC;AAAA,EAC3C;AAEA,QAAM,cAAc,eAAe,SAAS;AAC5C,QAAM,aAAa,CAAC;AAEpB,QAAM,eAAe,eAAe,UAAU;AAC9C,QAAM,cAAc,CAAC;AAErB,QAAM,qBAAqB,CAAC;AAC5B,QAAM,wBAAwB,CAAC;AAC/B,QAAM,sBAAsB,CAAC;AAC7B,QAAM,oBAAoB,CAAC;AAC3B,QAAM,kBAAkB,CAAC;AACzB,QAAM,kBAAkB,CAAC;AAEzB,QAAM,YAAY;AAClB,QAAM,gBAAgB;AACtB,QAAM,UAAU,IAAI;AACpB,QAAM,oBAAoB,IAAI;AAC9B,QAAM,uBAAuB,IAAI;AACjC,QAAM,oBAAoB,IAAI;AAC9B,QAAM,yBAAyB,IAAI;AACnC,QAAM,eAAe,IAAI;AACzB,QAAM,sBAAsB,IAAI;AAChC,QAAM,aAAa,IAAI;AACvB,QAAM,oBAAoB,IAAI;AAC9B,QAAM,cAAc,IAAI;AACxB,QAAM,SAAS;AACf,QAAM,qBAAqB;AAC3B,QAAM,mBAAmB,IAAI;AAC7B,QAAM,eAAe;AAErB,QAAM,cAAc;AACpB,QAAM,kBAAkB;AAExB,QAAM,mBAAmB,CAAC;AAE1B,WAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,UAAM,UAAU,IAAI,cAAc;AAClC,YAAQ,qBAAqB,eAAe,IAAI;AAChD,YAAQ,oBAAoB,eAAe,GAAG,GAC9C,QAAQ,oBAAoB,eAAe,GAAG;AAC9C,UAAM,iBAAiB,CAAC,IAAI;AAAA,EAChC;AAEA,QAAM,eAAe,eAAe,GAAG;AACvC,QAAM,gBAAgB,eAAe,GAAG;AACxC,QAAM,kBAAkB,eAAe,GAAG;AAG1C,SAAO,IAAI,UAAU,UAAU,GAAG,MAAM,QAAQ;AACpD;AAaO,SAAS,eAAe,SAC/B;AACI,MAAI,QAAQ,iBAAiB,OAAO;AAEpC,kBAAgB,MAAM,YAAY;AAClC,kBAAgB,MAAM,aAAa;AACnC,kBAAgB,MAAM,eAAe;AAErC,WAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,oBAAgB,MAAM,iBAAiB,CAAC,EAAE,kBAAkB;AAC5D,oBAAgB,MAAM,iBAAiB,CAAC,EAAE,iBAAiB;AAC3D,oBAAgB,MAAM,iBAAiB,CAAC,EAAE,iBAAiB;AAAA,EAC/D;AAEA,QAAM,mBAAmB;AAEzB,QAAM,qBAAqB;AAC3B,QAAM,wBAAwB;AAC9B,QAAM,sBAAsB;AAC5B,QAAM,oBAAoB;AAC1B,QAAM,kBAAkB;AACxB,QAAM,kBAAkB;AAExB,QAAM,gBAAgB,MAAM,WAAW;AAEvC,WAAS,IAAI,GAAG,IAAI,eAAe,EAAE,GACrC;AACI,UAAM,QAAQ,MAAM,WAAW,CAAC;AAEhC,QAAI,MAAM,OAAO,eACjB;AACI,YAAM,eAAe;AAAA,IACzB,OAEA;AACI,cAAQ,OAAO,MAAM,iBAAiB,IAAI;AAAA,IAC9C;AAAA,EACJ;AAEA,QAAM,YAAY;AAClB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,eAAe;AACrB,QAAM,aAAa;AACnB,QAAM,cAAc;AAEpB,QAAM,cAAc,MAAM,eAAe;AAEzC,WAAS,IAAI,GAAG,IAAI,aAAa,EAAE,GACnC;AACI,UAAM,MAAM,MAAM,eAAe,CAAC;AAElC,QAAI,IAAI,aAAa,eACrB;AACI,yBAAmB,OAAO,CAAC;AAAA,IAC/B;AAAA,EACJ;AAGA,QAAM,iBAAiB;AAEvB,iBAAe,MAAM,eAAe;AACpC,sBAAoB,MAAM,UAAU;AAEpC,kBAAgB,MAAM,UAAU;AAChC,kBAAgB,MAAM,WAAW;AACjC,kBAAgB,MAAM,WAAW;AACjC,kBAAgB,MAAM,aAAa;AACnC,kBAAgB,MAAM,WAAW;AACjC,kBAAgB,MAAM,YAAY;AAClC,kBAAgB,MAAM,eAAe;AAErC,0BAAwB,MAAM,cAAc;AAG5C,QAAM,WAAW,MAAM;AACvB,UAAQ,IAAI,QAAQ;AACpB,QAAM,UAAU;AAChB,QAAM,WAAW,WAAW;AAChC;AAEA,IAAM,gBAAgB,IAAI,OAAO;AACjC,IAAM,gBAAgB,IAAI,OAAO;AAEjC,SAAS,cAAc,YAAY,UAAU,aAAa,SAC1D;AAGI,QAAM,cAAc;AACpB,QAAM,QAAQ,YAAY;AAC1B,UAAQ,OAAO,cAAc,MAAM,WAAW;AAC9C,QAAM,cAAc,MAAM,iBAAiB,WAAW;AACtD,QAAM,cAAc,YAAY;AAChC,QAAM,SAAS,MAAM;AACrB,QAAM,SAAS,MAAM;AAErB,UAAQ,OAAO,aAAa,QAAQ;AAEpC,WAAS,IAAI,YAAY,IAAI,UAAU,EAAE,GACzC;AACI,UAAM,aAAa,YAAY,CAAC;AAEhC,UAAM,YAAY,WAAW;AAE7B,UAAM,SAAS,OAAO,WAAW,QAAQ;AACzC,UAAM,SAAS,OAAO,WAAW,QAAQ;AAGzC,UAAM,UAAU,gBAAgB,OAAO,SAAS,OAAO,OAAO;AAE9D,QAAI,CAAC,SACL;AACI,iBAAW,YAAY,kBAAkB;AACzC,iBAAW,YAAY,CAAC,kBAAkB;AAC1C,eAAS,YAAY,oBAAoB,SAAS;AAAA,IACtD,OAEA;AACI,YAAM,eAAe,WAAW,WAAW,kBAAkB,wBAAwB;AAGrF,YAAM,QAAQ,OAAO,OAAO,MAAM;AAClC,YAAM,QAAQ,OAAO,OAAO,MAAM;AAClC,YAAM,WAAW,aAAa,OAAO,KAAK;AAC1C,YAAM,WAAW,aAAa,OAAO,KAAK;AAG1C,iBAAW,gBAAgB,MAAM,aAAa,UAAU,cAAc,MAAM,aAAa;AACzF,iBAAW,WAAW,SAAS;AAC/B,iBAAW,QAAQ,SAAS;AAE5B,iBAAW,gBAAgB,MAAM,aAAa,UAAU,cAAc,MAAM,aAAa;AACzF,iBAAW,WAAW,SAAS;AAC/B,iBAAW,QAAQ,SAAS;AAE5B,YAAM,aAAa,SAAS;AAC5B,YAAM,aAAa,SAAS;AAG5B,oBAAc,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY;AAClG,oBAAc,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY;AAGlG,oBAAc,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY;AAClG,oBAAc,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY,IAAI,WAAW,EAAE,IAAI,SAAS,YAAY;AAGlG,YAAM,WAAW,gBAAgB,OAAO,YAAY,QAAQ,YAAY,eAAe,QAAQ,YAAY,aAAa;AAGxH,UAAI,YAAY,CAAC,aACjB;AACI,mBAAW,YAAY,kBAAkB;AACzC,iBAAS,YAAY,oBAAoB,SAAS;AAAA,MACtD,WACS,CAAC,YAAY,aACtB;AACI,mBAAW,YAAY,kBAAkB;AACzC,iBAAS,YAAY,oBAAoB,SAAS;AAAA,MACtD;AAAA,IACJ;AAAA,EACJ;AAGJ;AAEO,SAAS,wBAAwB,OAAO,SAAS,YACxD;AACI,UAAQ,OAAO,QAAQ,aAAa,UAAU,WAAW;AACzD,QAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AACtD,UAAQ,aAAa;AACrB,UAAQ,aAAa,IAAI,SAAS;AAClC,QAAM,gBAAgB,aAAa,IAAI,QAAQ;AAC/C,gBAAc,IAAI,UAAU;AAChC;AAEO,SAAS,2BAA2B,OAAO,UAAU,YAC5D;AAEI,QAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,QAAM,aAAa,gBAAgB,IAAI,UAAU,UAAU;AAE3D,MAAI,eAAe,eACnB;AACI,UAAM,kBAAkB,IAAI,SAAS,KAAK,UAAU;AAGpD,UAAM,eAAe,MAAM,aAAa,gBAAgB,SAAS;AACjE,YAAQ,OAAO,aAAa,aAAa,QAAQ;AACjD,YAAQ,OAAO,aAAa,eAAe,UAAU;AACrD,YAAQ,OAAO,aAAa,eAAe,aAAa;AACxD,iBAAa,aAAa;AAAA,EAC9B;AACJ;AAGO,SAAS,UAAU,SAC1B;AACI,QAAM,QAAQ,QAAQ;AAEtB,UAAQ,OAAO,MAAM,cAAc,CAAC;AAKpC,4BAA0B,MAAM,UAAU;AAG1C,MAAI,eAAe;AACnB,QAAM,cAAc,MAAM,gBAAgB;AAE1C,WAAS,IAAI,GAAG,IAAI,oBAAoB,EAAE,GAC1C;AACI,oBAAgB,YAAY,CAAC,EAAE,SAAS;AAAA,EAC5C;AAEA,QAAM,mBAAmB,MAAM,eAAe,UAAU,WAAW,EAAE,SAAS;AAC9E,kBAAgB;AAEhB,MAAI,gBAAgB,GACpB;AAEI;AAAA,EACJ;AAEA,QAAM,cAAc,CAAC;AAErB,MAAI,eAAe;AAEnB,WAAS,IAAI,GAAG,IAAI,oBAAoB,EAAE,GAC1C;AACI,UAAM,QAAQ,YAAY,CAAC;AAC3B,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,OAAO,MAAM,SAAS;AAE5B,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,cAAQ,OAAO,KAAK,CAAC,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,YAAY,EAAE;AACvF,cAAQ,OAAO,KAAK,CAAC,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,YAAY,EAAE;AACvF,kBAAY,KAAK,KAAK,CAAC,CAAC;AACxB,sBAAgB;AAAA,IACpB;AAAA,EACJ;AAEA;AACI,UAAM,OAAO,MAAM,eAAe,UAAU,WAAW,EAAE,SAAS;AAElE,aAAS,IAAI,GAAG,IAAI,kBAAkB,EAAE,GACxC;AACI,cAAQ,OAAO,KAAK,CAAC,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,YAAY,EAAE;AACzE,cAAQ,OAAO,KAAK,CAAC,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,YAAY,EAAE;AACzE,kBAAY,KAAK,KAAK,CAAC,CAAC;AACxB,cAAQ,OAAO,YAAY,YAAY,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,YAAY,EAAE;AAC3F,cAAQ,OAAO,YAAY,YAAY,EAAE,aAAa,eAAe,GAAG,CAAC,IAAI,YAAY,EAAE;AAC3F,sBAAgB;AAAA,IACpB;AAAA,EACJ;AAEA,UAAQ,OAAO,gBAAgB,YAAY;AAG3C,UAAQ,WAAW;AAGnB,QAAM,oBAAoB,gBAAgB,MAAM,aAAa;AAE7D,WAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,UAAM,iBAAiB,CAAC,EAAE,qBAAqB,sBAAsB,MAAM,iBAAiB,CAAC,EAAE,oBAAoB,iBAAiB;AAAA,EACxI;AAGA,gBAAc,GAAG,cAAc,GAAG,OAAO;AAGzC,UAAQ,WAAW;AAKnB,QAAM,SAAS,MAAM,iBAAiB,CAAC,EAAE;AAEzC,WAAS,IAAI,GAAG,IAAI,MAAM,aAAa,EAAE,GACzC;AACI,mBAAe,QAAQ,MAAM,iBAAiB,CAAC,EAAE,kBAAkB;AAAA,EACvE;AAEA,QAAM,WAAW,MAAM;AACvB,QAAM,WAAW,MAAM,eAAe,UAAU,WAAW;AAE3D,QAAM,SAAS,MAAM;AACrB,QAAM,UAAU,MAAM;AAGtB,WAAS,IAAI,GAAG,IAAI,OAAO,YAAY,EAAE,GACzC;AACI,QAAI,OAAO,OAAO,KAAK,CAAC;AAExB,WAAO,QAAQ,IACf;AACI,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,YAAY,KAAK,IAAI;AAE3B,YAAM,UAAU,SAAS,SAAS;AAClC,cAAQ,OAAO,QAAQ,YAAY,UAAU,WAAW;AAExD,YAAM,aAAa,QAAQ;AAC3B,YAAM,aAAa,QAAQ;AAE3B,UAAI;AAEJ,UAAI,cAAc,eAClB;AAEI,gBAAQ,OAAO,KAAK,cAAc,aAAa,kBAAkB;AACjE,cAAM,QAAQ,YAAY,UAAU;AACpC,gBAAQ,OAAO,KAAK,cAAc,aAAa,MAAM,SAAS,KAAK;AACnE,qBAAa,MAAM,SAAS,KAAK,UAAU;AAAA,MAC/C,OAEA;AACI,gBAAQ,OAAO,KAAK,cAAc,aAAa,SAAS,SAAS,KAAK;AACtE,qBAAa,SAAS,SAAS,KAAK,UAAU;AAAA,MAClD;AAEA,YAAM,SAAS,OAAO,QAAQ,QAAQ;AACtC,YAAM,SAAS,OAAO,QAAQ,QAAQ;AACtC,YAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,SAAS,OAAO,QAAQ;AACtE,YAAM,WAAW,IAAI,UAAU,OAAO,KAAK,GAAG,SAAS,OAAO,QAAQ;AACtE,YAAM,QAAQ,QAAQ;AACtB,YAAM,WAAW,WAAW;AAE5B,UAAI,WAAW,kBAAkB,gBACjC;AAEI,aAAK,QAAQ,eAAe,2BAA2B,MAAM,QAAQ,eAAe,kCAAkC,GACtH;AACI,gBAAM,QAAQ,IAAI,uBAAuB;AACzC,gBAAM,WAAW;AACjB,gBAAM,WAAW;AACjB,gBAAM,gBAAgB,KAAK,KAAK;AAAA,QACpC;AAGA,gBAAQ,SAAS,CAAC,eAAe;AACjC,yBAAiB,OAAO,SAAS,KAAK;AAAA,MAI1C,WACS,WAAW,kBAAkB,uBACtC;AACI,gBAAQ,OAAO,QAAQ,YAAY,aAAa;AAEhD,aAAK,QAAQ,eAAe,yBAAyB,GACrD;AAEI,eAAK,QAAQ,eAAe,iCAAiC,GAC7D;AACI,gBAAI,OAAO,UACX;AACI,oBAAM,QAAQ,IAAI,wBAAwB;AAC1C,oBAAM,gBAAgB;AACtB,oBAAM,iBAAiB;AACvB,oBAAM,sBAAsB,KAAK,KAAK;AAAA,YAC1C;AAEA,gBAAI,OAAO,UACX;AACI,oBAAM,QAAQ,IAAI,wBAAwB;AAC1C,oBAAM,gBAAgB;AACtB,oBAAM,iBAAiB;AACvB,oBAAM,sBAAsB,KAAK,KAAK;AAAA,YAC1C;AAAA,UACJ;AAEA,qBAAW,YAAY,CAAC,kBAAkB;AAC1C,kBAAQ,SAAS,eAAe;AAAA,QACpC,OAEA;AAEI,cAAI,QAAQ,eAAe,+BAC3B;AACI,kBAAM,QAAQ,IAAI,yBAAyB;AAC3C,kBAAM,WAAW;AACjB,kBAAM,WAAW;AACjB,kBAAM,WAAW,WAAW;AAC5B,kBAAM,kBAAkB,KAAK,KAAK;AAAA,UACtC;AAEA,kBAAQ,OAAO,WAAW,SAAS,aAAa,CAAC;AACjD,kBAAQ,OAAO,QAAQ,YAAY,UAAU,WAAW;AAIxD,kBAAQ,SAAS,eAAe;AAChC,wBAAc,OAAO,OAAO;AAG5B,kBAAQ,OAAO,QAAQ,cAAc,aAAa;AAClD,kBAAQ,OAAO,QAAQ,cAAc,UAAU;AAI/C,kBAAQ,OAAO,KAAK,cAAc,aAAa,SAAS,SAAS,KAAK;AACtE,uBAAa,SAAS,SAAS,KAAK,UAAU;AAE9C,qBAAW,YAAY,CAAC,kBAAkB;AAE1C,8BAAoB,OAAO,YAAY,OAAO;AAC9C,qCAA2B,OAAO,UAAU,aAAa,UAAU;AAAA,QAGvE;AAAA,MACJ,WACS,WAAW,kBAAkB,uBACtC;AACI,mBAAW,YAAY,CAAC,kBAAkB;AAE1C,aAAK,QAAQ,eAAe,yBAAyB,GACrD;AAEI,kBAAQ,SAAS,CAAC,eAAe;AAEjC,eAAK,QAAQ,eAAe,iCAAiC,GAC7D;AACI,gBAAI,OAAO,UACX;AACI,oBAAM,QAAQ,IAAI,sBAAsB;AACxC,oBAAM,gBAAgB;AACtB,oBAAM,iBAAiB;AACvB,oBAAM,oBAAoB,KAAK,KAAK;AAAA,YACxC;AAEA,gBAAI,OAAO,UACX;AACI,oBAAM,QAAQ,IAAI,sBAAsB;AACxC,oBAAM,gBAAgB;AACtB,oBAAM,iBAAiB;AACvB,oBAAM,oBAAoB,KAAK,KAAK;AAAA,YACxC;AAAA,UACJ;AAAA,QACJ,OAEA;AAEI,kBAAQ,SAAS,CAAC,eAAe;AAEjC,cAAI,QAAQ,QAAQ,eAAe,+BACnC;AACI,kBAAM,QAAQ,IAAI,uBAAuB;AACzC,kBAAM,WAAW;AACjB,kBAAM,WAAW;AACjB,kBAAM,gBAAgB,KAAK,KAAK;AAAA,UACpC;AAEA,kBAAQ,OAAO,WAAW,SAAS,cAAc,CAAC;AAElD,0BAAgB,OAAO,OAAO;AAC9B,gBAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,gBAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AAEjC,kCAAwB,OAAO,SAAS,UAAU;AAClD,mCAAyB,OAAO,SAAS,SAAS,YAAY,UAAU;AAAA,QAI5E;AAAA,MACJ;AAGA,aAAO,OAAQ,OAAO;AAAA,IAC1B;AAAA,EACJ;AAEA,uBAAqB,KAAK;AAC1B,qBAAmB,KAAK;AAI5B;AAEA,YAAY,cAAc;AAC1B,YAAY,QAAQ,CAAC;AACrB,YAAY,cAAc;AAC1B,YAAY,QAAQ,CAAC;AACrB,YAAY,kBAAkB;AAC9B,YAAY,uBAAuB;AACnC,qBAAqB,QAAQ,CAAC;AAC9B,YAAY,qBAAqB;AACjC,YAAY,oBAAoB;AAChC,YAAY,kBAAkB;AAC9B,YAAY,4BAA4B;AACxC,YAAY,eAAe;AAmBpB,SAAS,aAAa,SAAS,UAAU,cAChD;AACI,cAAY;AAEZ,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAIA,QAAM,qBAAqB,CAAC;AAC5B,QAAM,wBAAwB,CAAC;AAC/B,QAAM,sBAAsB,CAAC;AAC7B,QAAM,oBAAoB,CAAC;AAC3B,QAAM,kBAAkB,CAAC;AACzB,QAAM,kBAAkB,CAAC;AAEzB,MAAI,aAAa,GACjB;AAEI;AAAA,EACJ;AAEA,QAAM,SAAS;AACf,0BAAwB,KAAK;AAE7B,QAAM,UAAU,IAAI,cAAc;AAClC,UAAQ,QAAQ;AAChB,UAAQ,KAAK;AACb,UAAQ,eAAe,KAAK,IAAI,GAAG,YAAY;AAE/C,MAAI,WAAW,GACf;AACI,YAAQ,SAAS,IAAM;AACvB,YAAQ,IAAI,WAAW,QAAQ;AAC/B,YAAQ,QAAQ,QAAQ,eAAe,QAAQ;AAAA,EACnD,OAEA;AACI,YAAQ,SAAS;AACjB,YAAQ,IAAI;AACZ,YAAQ,QAAQ;AAAA,EACpB;AAEA,QAAM,QAAQ,QAAQ;AAGtB,QAAM,eAAe,KAAK,IAAI,MAAM,cAAc,OAAO,QAAQ,KAAK;AACtE,QAAM,aAAa,KAAK,IAAI,MAAM,YAAY,QAAQ,QAAQ,KAAK;AAEnE,UAAQ,kBAAkB,WAAW,cAAc,MAAM,qBAAqB,QAAQ,CAAC;AACvF,UAAQ,iBAAiB,WAAW,IAAM,cAAc,MAAM,qBAAqB,QAAQ,CAAC;AAC5F,UAAQ,gBAAgB,WAAW,YAAY,MAAM,mBAAmB,QAAQ,CAAC;AAEjF,UAAQ,uBAAuB,MAAM;AACrC,UAAQ,oBAAoB,MAAM;AAClC,UAAQ,qBAAqB,MAAM;AAGnC,YAAU,OAAO;AAGjB,MAAI,QAAQ,KAAK,GACjB;AACI,YAAQ,OAAO,OAAO;AAAA,EAC1B;AAEA,QAAM,SAAS;AAEf,UAAQ,OAAO,qBAAqB,MAAM,cAAc,KAAK,GAAG,0CAA0C,qBAAqB,MAAM,cAAc,CAAC,EAAE;AAC1J;AAEA,IAAMC,MAAK,IAAI,OAAO;AACtB,IAAMC,MAAK,IAAI,OAAO;AACtB,IAAM,IAAI,IAAI,MAAM;AACpB,IAAM,MAAM,IAAI,YAAYD,KAAI,CAAC;AAE1B,SAAS,YAAY,MAAM,OAAO,WAAW,OACpD;AACI,QAAME,MAAK,UAAU,MAAM;AAE3B,UAAQ,MAAM,MACd;AAAA,IACI,KAAK,YAAY;AACb;AACI,cAAM,UAAU,MAAM;AACtB,4BAAoBA,KAAI,QAAQ,SAASF,GAAE;AAC3C,4BAAoBE,KAAI,QAAQ,SAASD,GAAE;AAE3C,YAAI,MAAM,OACV;AACI,eAAK,iBAAiBD,KAAIC,KAAI,QAAQ,QAAQ,OAAO,KAAK,OAAO;AAAA,QACrE,WACS,CAAC,MAAM,cAChB;AACI,eAAK,iBAAiBD,KAAIC,KAAI,QAAQ,QAAQ,OAAO,KAAK,OAAO;AAAA,QACrE;AAAA,MACJ;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,SAAS,MAAM;AACrB,8BAAsBC,KAAI,OAAO,QAAQ,GAAG;AAE5C,YAAI,MAAM,OACV;AACI,eAAK,gBAAgB,KAAK,OAAO,QAAQ,OAAO,KAAK,OAAO;AAAA,QAChE,WACS,CAAC,MAAM,cAChB;AACI,eAAK,gBAAgB,KAAK,OAAO,QAAQ,OAAO,KAAK,OAAO;AAAA,QAChE;AAAA,MACJ;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,OAAO,MAAM;AAEnB,YAAI,MAAM,OACV;AACI,eAAK,iBAAiBA,KAAI,OAAO,KAAK,OAAO;AAAA,QACjD,WACS,CAAC,MAAM,cAChB;AACI,eAAK,iBAAiBA,KAAI,KAAK,UAAU,KAAK,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO;AAAA,QACzF;AAAA,MACJ;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,UAAU,MAAM;AACtB,4BAAoBA,KAAI,QAAQ,QAAQF,GAAE;AAC1C,4BAAoBE,KAAI,QAAQ,QAAQD,GAAE;AAE1C,YAAI,CAAC,MAAM,cACX;AACI,eAAK,YAAYD,KAAIC,KAAI,OAAO,KAAK,OAAO;AAAA,QAChD;AAAA,MACJ;AAEA;AAAA,IAEJ,KAAK,YAAY;AACb;AACI,cAAM,UAAU,MAAM,aAAa;AACnC,4BAAoBC,KAAI,QAAQ,QAAQF,GAAE;AAC1C,4BAAoBE,KAAI,QAAQ,QAAQD,GAAE;AAE1C,YAAI,CAAC,MAAM,cACX;AACI,eAAK,YAAYD,KAAIC,KAAI,OAAO,KAAK,OAAO;AAAA,QAChD;AAAA,MAIJ;AAEA;AAAA,IAEJ;AACI;AAAA,EACR;AACJ;AAGA,IAAM,cAAN,MACA;AAAA,EACI,YAAY,OAAO,MACnB;AACI,SAAK,QAAQ;AACb,SAAK,OAAO;AAAA,EAEhB;AACJ;AAEA,SAAS,kBAAkB,SAAS,SAAS,SAC7C;AAGI,QAAM,cAAc;AACpB,QAAM,QAAQ,YAAY;AAC1B,QAAM,OAAO,YAAY;AAGzB,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,WAAS,MAAM,cAAc,MAAM,MAAM;AAEzC,MAAI,KAAK,YACT;AAEI,UAAM,OAAO,MAAM,UAAU,MAAM,MAAM;AACzC,UAAM,UAAU,aAAa,OAAO,IAAI;AAExC,QAAI;AAEJ,QAAI,KAAK,YAAY,UAAU,qBAC/B;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,MAAM,gBAAgB,GAC/B;AACI,cAAQ,MAAM;AAAA,IAClB,WACS,KAAK,SAAS,WAAW,kBAAkB,QAAQ,SAAS,GACrE;AAEI,cAAQ,WAAW;AAAA,IACvB,WACS,KAAK,aAAa,UAAU,gBACrC;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,MAAM,UACf;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,QAAQ,YAAY,KAAK,aAAa,UAAU,aACzD;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,KAAK,eACd;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,QAAQ,QACjB;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,KAAK,SAAS,WAAW,eAClC;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,KAAK,SAAS,WAAW,kBAClC;AACI,cAAQ,WAAW;AAAA,IACvB,WACS,KAAK,aAAa,UAAU,aACrC;AACI,cAAQ,WAAW;AAAA,IACvB,OAEA;AACI,cAAQ,WAAW;AAAA,IACvB;AAEA,gBAAY,MAAM,OAAO,QAAQ,WAAW,KAAK;AAAA,EACrD;AAEA,MAAI,KAAK,WACT;AACI,UAAM,OAAO,MAAM;AAEnB,UAAM,KAAK;AAAA,MACP,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,MAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,MAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,MAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,IACjD;AAEA,SAAK,YAAY,IAAI,GAAG,WAAW,cAAc,KAAK,OAAO;AAAA,EACjE;AAEA,SAAO;AACX;AAEA,SAAS,iBAAiB,OAAO,MACjC;AACI,UAAQ,OAAO,eAAe,KAAK,aAAa,CAAC;AAEjD,QAAM,iBAAiB;AACvB,QAAM,cAAc;AACpB,QAAM,mBAAmB,WAAW;AACpC,QAAM,WAAW,WAAW;AAC5B,QAAM,eAAe,WAAW;AAChC,QAAM,cAAc,WAAW;AAC/B,QAAM,eAAe,WAAW;AAChC,QAAM,gBAAgB,WAAW;AAEjC,QAAM,cAAc;AAAA,IAAE,WAAW;AAAA,IAAa,WAAW;AAAA,IAAgB,WAAW;AAAA,IAAgB,WAAW;AAAA,IAC3G,WAAW;AAAA,IAAc,WAAW;AAAA,IAAc,WAAW;AAAA,IAAgB,WAAW;AAAA,IACxF,WAAW;AAAA,IAAmB,WAAW;AAAA,IAAmB,WAAW;AAAA,IAAe,WAAW;AAAA,EAAc;AAEnH,QAAM,eAAe,gBAAgB,MAAM,UAAU;AACrD,QAAM,eAAe,sBAAsB,MAAM,cAAc,YAAY;AAE3E,QAAM,gBAAgB,gBAAgB,MAAM,WAAW;AACvD,QAAM,gBAAgB,sBAAsB,MAAM,eAAe,aAAa;AAE9E,QAAM,kBAAkB,gBAAgB,MAAM,aAAa;AAC3D,QAAM,kBAAkB,sBAAsB,MAAM,iBAAiB,eAAe;AAEpF,QAAM,cAAc,IAAI,YAAY,OAAO,IAAI;AAE/C,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI;AAAA,MAAoB,MAAM,WAAW,MAAM,CAAC;AAAA,MAAG,KAAK;AAAA,MAAe;AAAA,MAAsB;AAAA,MACrF;AAAA,IAAW;AAAA,EACnB;AAEA,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,OAAO,MAAM,aAAa;AAEhC,WAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GACjC;AACI,QAAI,OAAO,KAAK,CAAC;AAEjB,WAAO,SAAS,GAChB;AACI,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,SAAS,KAAK,IAAI;AAGxB,YAAM,OAAO,MAAM,UAAU,MAAM;AAEnC,UAAI,KAAK,YAAY,KAAK,SAAS,WAAW,gBAC9C;AACI,cAAM,SAAS,IAAI,OAAO,KAAK,GAAG;AAClC,cAAM,UAAU,aAAa,OAAO,IAAI;AAExC,cAAM,YAAY,IAAI,YAAY,QAAQ,QAAQ,QAAQ,UAAU,CAAC;AACrE,aAAK,cAAc,WAAW,KAAK,OAAO;AAE1C,cAAME,KAAI,iBAAiB,WAAW,MAAM;AAE5C,cAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,CAAC,CAAC;AAC3C,aAAK,WAAWA,IAAG,QAAQ,KAAK,OAAO;AAAA,MAC3C;AAEA,UAAI,KAAK,YACT;AACI,YAAI,WAAW,KAAK;AAEpB,eAAO,aAAa,eACpB;AACI,gBAAM,UAAU,YAAY;AAC5B,gBAAM,YAAY,WAAW;AAC7B,gBAAM,QAAQ,MAAM,WAAW,OAAO;AAGtC,cAAIC,UAAS,MAAM,eAAe,OAAO,MAAM,OAC/C;AACI,wBAAY,MAAM,OAAO,KAAK;AAC9B,qBAAS,MAAM,eAAe,OAAO;AAAA,UACzC;AAEA,qBAAW,MAAM,MAAM,SAAS,EAAE;AAAA,QACtC;AAAA,MACJ;AAEA,YAAM,aAAa;AAEnB,UAAI,KAAK,gBAAgB,KAAK,SAAS,WAAW,kBAAkB,KAAK,aAAa,UAAU,aAChG;AACI,YAAI,aAAa,KAAK;AAEtB,eAAO,eAAe,eACtB;AACI,gBAAM,YAAY,cAAc;AAChC,gBAAM,YAAY,aAAa;AAC/B,gBAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,uBAAa,QAAQ,MAAM,SAAS,EAAE;AAEtC,cAAI,QAAQ,aAAa,UAAU,eAAe,QAAQ,eAAe,eACzE;AACI;AAAA,UACJ;AAGA,cAAIA,UAAS,MAAM,iBAAiB,SAAS,MAAM,OACnD;AACI,oBAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,aAAa,kBAAkB;AAEjF,kBAAM,KAAK,MAAM,gBAAgB,OAAO,QAAQ,UAAU;AAC1D,oBAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,aAAa,GAAG,SAAS,KAAK;AAEhF,kBAAM,aAAa,GAAG,SAAS,KAAK,QAAQ,UAAU;AACtD,kBAAM,aAAa,WAAW,SAAS;AACvC,kBAAM,SAAS,IAAI,OAAO,WAAW,SAAS,SAAS,WAAW,SAAS,OAAO;AAElF,qBAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,oBAAM,QAAQ,WAAW,SAAS,OAAO,CAAC;AAE1C,kBAAI,KAAK,iBACT;AAEI,sBAAM,YAAY,QAAQ,eAAe,mBAAmB,MAAM;AAClE,qBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,WAAW,YAAY,QAAQ,UAAU,GAAG,KAAK,OAAO;AAAA,cACvG,WACS,MAAM,aAAa,YAC5B;AAEI,qBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,GAAK,kBAAkB,KAAK,OAAO;AAAA,cAClF,WACS,MAAM,cAAc,OAC7B;AAEI,qBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,IAAM,UAAU,KAAK,OAAO;AAAA,cAC3E,WACS,MAAM,cAAc,MAC7B;AAEI,qBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,GAAK,cAAc,KAAK,OAAO;AAAA,cAC9E;AAEA,kBAAI,KAAK,oBACT;AACI,sBAAMJ,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,sBAAMC,MAAK,SAASD,KAAI,aAAa,MAAM;AAC3C,qBAAK,YAAYA,KAAIC,KAAI,aAAa,KAAK,OAAO;AAAA,cACtD,WACS,KAAK,qBACd;AACI,sBAAMD,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,sBAAMC,MAAK,SAASD,KAAI,iBAAiB,MAAM,eAAe,MAAM;AACpE,qBAAK,YAAYA,KAAIC,KAAI,cAAc,KAAK,OAAO;AACnD,sBAAM,SAAS,IAAI,MAAS,MAAM,eAAe,QAAQ,CAAC,CAAC;AAC3D,qBAAK,WAAWD,KAAI,QAAQ,KAAK,OAAO;AAAA,cAC5C;AAEA,kBAAI,KAAK,sBACT;AACI,sBAAM,UAAU,YAAY,MAAM;AAClC,sBAAMA,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,sBAAMC,MAAK,SAASD,KAAI,iBAAiB,MAAM,gBAAgB,OAAO;AACtE,qBAAK,YAAYA,KAAIC,KAAI,eAAe,KAAK,OAAO;AACpD,sBAAM,SAAS,IAAI,MAAS,MAAM,gBAAgB,QAAQ,CAAC,CAAC;AAC5D,qBAAK,WAAWD,KAAI,QAAQ,KAAK,OAAO;AAAA,cAC5C;AAAA,YACJ;AAEA,qBAAS,MAAM,iBAAiB,SAAS;AAAA,UAC7C;AAEA,uBAAa,QAAQ,MAAM,SAAS,EAAE;AAAA,QAC1C;AAAA,MACJ;AAGA,aAAO,OAAQ,OAAO;AAAA,IAC1B;AAAA,EACJ;AACJ;AAoBO,SAAS,aAAa,SAAS,MACtC;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,MAAI,KAAK,kBACT;AACI,qBAAiB,OAAO,IAAI;AAE5B;AAAA,EACJ;AAEA,MAAI,KAAK,YACT;AACI,UAAM,WAAW,MAAM,eAAe;AAEtC,aAAS,WAAW,GAAG,WAAW,UAAU,EAAE,UAC9C;AACI,YAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,YAAM,YAAY,IAAI,KAAK;AAE3B,eAAS,YAAY,GAAG,YAAY,WAAW,EAAE,WACjD;AACI,cAAM,UAAU,IAAI,KAAK,KAAK,SAAS;AACvC,gBAAQ,OAAO,QAAQ,aAAa,MAAM,gCAAgC,QAAQ,SAAS,MAAM,WAAW,MAAM,SAAS;AAG3H,cAAM,OAAO,MAAM,UAAU,QAAQ,MAAM;AAG3C,gBAAQ,OAAO,KAAK,aAAa,UAAU,2BAA2B,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAEpG,cAAME,MAAK,QAAQ;AACnB,YAAI,UAAU,KAAK;AAEnB,eAAO,YAAY,eACnB;AACI,gBAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,cAAI;AAEJ,cAAI,KAAK,YAAY,UAAU,qBAC/B;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,MAAM,gBAAgB,GAC/B;AACI,oBAAQ,MAAM;AAAA,UAClB,WACS,KAAK,SAAS,WAAW,kBAAkB,QAAQ,SAAS,GACrE;AAEI,oBAAQ,WAAW;AAAA,UACvB,WACS,KAAK,aAAa,UAAU,gBACrC;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,MAAM,UACf;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,QAAQ,YAAY,KAAK,aAAa,UAAU,aACzD;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,KAAK,eACd;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,QAAQ,QACjB;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,KAAK,SAAS,WAAW,eAClC;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,KAAK,SAAS,WAAW,kBAClC;AACI,oBAAQ,WAAW;AAAA,UACvB,WACS,KAAK,aAAa,UAAU,aACrC;AACI,oBAAQ,WAAW;AAAA,UACvB,OAEA;AACI,oBAAQ,WAAW;AAAA,UACvB;AAEA,sBAAY,MAAM,OAAOA,KAAI,KAAK;AAClC,oBAAU,MAAM;AAAA,QACpB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,KAAK,YACT;AACI,UAAM,QAAQ,MAAM,WAAW;AAE/B,aAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAC7B;AACI,YAAM,QAAQ,MAAM,WAAW,CAAC;AAEhC,UAAI,MAAM,aAAa,eACvB;AACI;AAAA,MACJ;AAEA,kBAAY,MAAM,OAAO,KAAK;AAAA,IAClC;AAAA,EACJ;AAEA,MAAI,KAAK,WACT;AACI,UAAM,QAAQ,WAAW;AACzB,UAAM,WAAW,UAAU;AAE3B;AACI,YAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,YAAM,YAAY,IAAI,KAAK;AAE3B,eAAS,YAAY,GAAG,YAAY,WAAW,EAAE,WACjD;AACI,cAAM,UAAU,IAAI,KAAK,KAAK,SAAS;AACvC,cAAMA,MAAK,YAAY,SAAS;AAMhC,cAAM,OAAO,MAAM,UAAU,QAAQ,MAAM;AAC3C,gBAAQ,OAAO,KAAK,aAAa,QAAQ;AAEzC,YAAI,UAAU,KAAK;AAEnB,eAAO,YAAY,eACnB;AACI,gBAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,gBAAM,OAAO,MAAM;AACnB,gBAAM,KAAK;AAAA,YACP,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,YAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,YAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,YAC7C,IAAI,OAAO,KAAK,aAAa,KAAK,WAAW;AAAA,UACjD;AAEA,eAAK,YAAYA,KAAI,IAAI,GAAG,OAAO,KAAK,OAAO;AAE/C,oBAAU,MAAM;AAAA,QACpB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,KAAK,UACT;AACI,UAAM,SAAS,IAAI,OAAO,KAAK,GAAG;AAClC,UAAM,WAAW,MAAM,eAAe;AAEtC,aAAS,WAAW,GAAG,WAAW,UAAU,EAAE,UAC9C;AACI,YAAM,MAAM,MAAM,eAAe,QAAQ;AACzC,YAAM,YAAY,IAAI,KAAK;AAE3B,eAAS,YAAY,GAAG,YAAY,WAAW,EAAE,WACjD;AACI,cAAM,UAAU,IAAI,KAAK,KAAK,SAAS;AAEvC,cAAM,YAAY,IAAI,YAAY,QAAQ,QAAQ,QAAQ,UAAU,CAAC;AACrE,aAAK,cAAc,WAAW,KAAK,OAAO;AAE1C,cAAMC,KAAI,iBAAiB,WAAW,MAAM;AAE5C,cAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,CAAC,CAAC;AAC3C,aAAK,WAAWA,IAAG,QAAQ,KAAK,OAAO;AAAA,MAC3C;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,KAAK,cACT;AACI,UAAM,iBAAiB;AACvB,UAAM,cAAc;AACpB,UAAM,aAAa;AAEnB,UAAM,mBAAmB,WAAW;AACpC,UAAM,WAAW,WAAW;AAC5B,UAAM,eAAe,WAAW;AAChC,UAAM,cAAc,WAAW;AAC/B,UAAM,eAAe,WAAW;AAChC,UAAM,gBAAgB,WAAW;AAEjC,UAAM,SAAS;AAAA,MAAE,WAAW;AAAA,MAAa,WAAW;AAAA,MAAgB,WAAW;AAAA,MAAgB,WAAW;AAAA,MACtG,WAAW;AAAA,MAAc,WAAW;AAAA,MAAc,WAAW;AAAA,MAAgB,WAAW;AAAA,MACxF,WAAW;AAAA,MAAmB,WAAW;AAAA,MAAmB,WAAW;AAAA,MAAe,WAAW;AAAA,IAAc;AAEnH,aAAS,aAAa,GAAG,aAAa,oBAAoB,EAAE,YAC5D;AACI,YAAM,aAAa,MAAM,gBAAgB,OAAO,UAAU;AAE1D,YAAM,eAAe,WAAW,SAAS;AAEzC,eAAS,eAAe,GAAG,eAAe,cAAc,EAAE,cAC1D;AACI,cAAM,UAAU,WAAW,SAAS,KAAK,YAAY;AACrD,cAAM,aAAa,QAAQ,SAAS;AACpC,cAAM,SAAS,IAAI,OAAO,QAAQ,SAAS,SAAS,QAAQ,SAAS,OAAO;AAE5E,iBAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAClC;AACI,gBAAM,QAAQ,QAAQ,SAAS,OAAO,CAAC;AAEvC,cAAI,KAAK,mBAAmB,KAAK,cAAc,cAAc,oBAC7D;AAEI,kBAAM,YAAY,eAAe,mBAAmB,MAAM;AAC1D,iBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,WAAW,OAAO,UAAU,GAAG,KAAK,OAAO;AAAA,UAG1F,WACS,MAAM,aAAa,YAC5B;AAEI,iBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,GAAK,kBAAkB,KAAK,OAAO;AAAA,UAClF,WACS,MAAM,cAAc,OAC7B;AAEI,iBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,IAAM,UAAU,KAAK,OAAO;AAAA,UAC3E,WACS,MAAM,cAAc,MAC7B;AAEI,iBAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,GAAK,cAAc,KAAK,OAAO;AAAA,UAC9E;AAEA,cAAI,KAAK,oBACT;AACI,kBAAMH,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,kBAAMC,MAAK,SAASD,KAAI,aAAa,MAAM;AAC3C,iBAAK,YAAYA,KAAIC,KAAI,aAAa,KAAK,OAAO;AAAA,UACtD,WACS,KAAK,qBACd;AACI,kBAAMD,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,kBAAMC,MAAK,SAASD,KAAI,iBAAiB,MAAM,eAAe,MAAM;AACpE,iBAAK,YAAYA,KAAIC,KAAI,cAAc,KAAK,OAAO;AACnD,kBAAM,SAAS,IAAI,MAAS,MAAM,eAAe,QAAQ,CAAC,CAAC;AAC3D,iBAAK,WAAWD,KAAI,QAAQ,KAAK,OAAO;AAAA,UAC5C;AAEA,cAAI,KAAK,sBACT;AACI,kBAAM,UAAU,YAAY,MAAM;AAClC,kBAAMA,MAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,MAAM;AAChD,kBAAMC,MAAK,SAASD,KAAI,iBAAiB,MAAM,gBAAgB,OAAO;AACtE,iBAAK,YAAYA,KAAIC,KAAI,eAAe,KAAK,OAAO;AACpD,kBAAM,SAAS,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC;AAChD,iBAAK,WAAWD,KAAI,QAAQ,KAAK,OAAO;AAAA,UAC5C;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;AAYO,SAAS,sBAAsB,SACtC;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,aAAa;AAAA,EAC5B;AAEA,QAAM,QAAQ,MAAM,mBAAmB;AACvC,QAAM,SAAS,IAAI,aAAa;AAChC,SAAO,aAAa,MAAM;AAC1B,SAAO,YAAY;AAEnB,SAAO;AACX;AAYO,SAAS,wBAAwB,SACxC;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,eAAe;AAAA,EAC9B;AAEA,QAAM,aAAa,MAAM,sBAAsB;AAC/C,QAAM,WAAW,MAAM,oBAAoB;AAE3C,QAAM,SAAS,IAAI,eAAe;AAClC,SAAO,cAAc,MAAM;AAC3B,SAAO,YAAY,MAAM;AACzB,SAAO,aAAa;AACpB,SAAO,WAAW;AAElB,SAAO;AACX;AAeO,SAAS,yBAAyB,SACzC;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO,IAAI,gBAAgB;AAAA,EAC/B;AAEA,QAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAM,WAAW,MAAM,gBAAgB;AACvC,QAAM,WAAW,MAAM,gBAAgB;AAEvC,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,cAAc,MAAM;AAC3B,SAAO,YAAY,MAAM;AACzB,SAAO,YAAY,MAAM;AACzB,SAAO,aAAa;AACpB,SAAO,WAAW;AAClB,SAAO,WAAW;AAElB,SAAO;AACX;AAcO,SAAS,gBAAgB,IAChC;AACI,MAAI,OAAO,QACX;AACI,WAAO;AAAA,EACX;AAEA,MAAI,GAAG,SAAS,KAAK,gBAAgB,GAAG,QACxC;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,GAAG,SAAS,CAAC;AAErC,MAAI,MAAM,YAAY,GAAG,SAAS,GAClC;AAEI,WAAO;AAAA,EACX;AAEA,SAAO,GAAG,aAAa,MAAM;AACjC;AAeO,SAAS,eAAe,IAC/B;AACI,MAAI,OAAO,QACX;AACI,WAAO;AAAA,EACX;AAEA,MAAI,EAAE,cAAc,WACpB;AACI,YAAQ,MAAM;AAAA,EAAgB,IAAI,MAAM,EAAE,KAAK,EAAE;AAEjD,WAAO;AAAA,EACX;AAEA,MAAI,GAAG,SAAS,KAAK,iBAAiB,GAAG,QACzC;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,GAAG,MAAM;AAEjC,MAAI,MAAM,YAAY,GAAG,QACzB;AAEI,WAAO;AAAA,EACX;AAEA,MAAI,GAAG,SAAS,KAAK,MAAM,UAAU,SAAS,GAAG,QACjD;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,MAAM,UAAU,GAAG,SAAS,CAAC;AAE1C,MAAI,KAAK,aAAa,eACtB;AAEI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,KAAK,cAAc,aAAa;AAE/C,MAAI,KAAK,aAAa,GAAG,UACzB;AAEI,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAgBO,SAAS,gBAAgB,IAChC;AACI,MAAI,OAAO,QACX;AACI,WAAO;AAAA,EACX;AAEA,MAAI,iBAAiB,GAAG,QACxB;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,GAAG,MAAM;AAEjC,MAAI,MAAM,YAAY,GAAG,QACzB;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,GAAG,SAAS;AAE5B,MAAI,UAAU,KAAK,MAAM,WAAW,UAAU,SAC9C;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,MAAI,MAAM,OAAO,eACjB;AAEI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,MAAM,MAAM,OAAO;AAElC,SAAO,GAAG,aAAa,MAAM;AACjC;AAkBO,SAAS,gBAAgB,IAChC;AACI,MAAI,OAAO,QACX;AACI,WAAO;AAAA,EACX;AAEA,MAAI,GAAG,SAAS,KAAK,iBAAiB,GAAG,QACzC;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,GAAG,MAAM;AAEjC,MAAI,MAAM,YAAY,GAAG,QACzB;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,GAAG,SAAS;AAE5B,MAAI,UAAU,KAAK,MAAM,WAAW,UAAU,SAC9C;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,MAAI,MAAM,OAAO,eACjB;AAEI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,MAAM,MAAM,OAAO;AAElC,SAAO,GAAG,aAAa,MAAM;AACjC;AAiBO,SAAS,gBAAgB,IAChC;AACI,MAAI,OAAO,QACX;AACI,WAAO;AAAA,EACX;AAEA,MAAI,GAAG,SAAS,KAAK,iBAAiB,GAAG,QACzC;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,UAAU,GAAG,MAAM;AAEjC,MAAI,MAAM,YAAY,GAAG,QACzB;AAEI,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,GAAG,SAAS;AAE5B,MAAI,UAAU,KAAK,MAAM,WAAW,UAAU,SAC9C;AACI,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,MAAI,MAAM,YAAY,eACtB;AAEI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,MAAM,WAAW,OAAO;AAEvC,SAAO,GAAG,aAAa,MAAM;AACjC;AAcO,SAAS,uBAAuB,SAAS,MAChD;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,MAAI,SAAS,MAAM,aACnB;AACI;AAAA,EACJ;AAEA,QAAM,cAAc;AAEpB,MAAI,SAAS,OACb;AACI,UAAM,WAAW,MAAM,eAAe;AAEtC,aAAS,IAAI,UAAU,qBAAqB,IAAI,UAAU,EAAE,GAC5D;AACI,YAAM,MAAM,MAAM,eAAe,CAAC;AAElC,UAAI,IAAI,KAAK,SAAS,GACtB;AACI,wBAAgB,OAAO,CAAC;AAAA,MAC5B;AAAA,IACJ;AAAA,EACJ;AACJ;AAaO,SAAS,2BAA2B,SAAS,MACpD;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,qBAAqB;AAC/B;AAaO,SAAS,yBAAyB,SAAS,MAClD;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,mBAAmB;AAC7B;AAcO,SAAS,gCAAgC,SAAS,OACzD;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,uBAAuB,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO,SAAS,CAAC;AAC9E;AAYO,SAAS,6BAA6B,SAAS,OACtD;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,oBAAoB,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO,SAAS,CAAC;AAC3E;AAgBO,SAAS,yBAAyB,SAAS,OAAO,cAAc,SACvE;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,eAAe,aAAa,OAAO,GAAK,OAAO,SAAS;AAC9D,QAAM,sBAAsB,aAAa,cAAc,GAAK,OAAO,SAAS;AAC5E,QAAM,yBAAyB,aAAa,SAAS,GAAK,OAAO,SAAS;AAC9E;AA+BA,SAAS,kBAAkB,SAAS,SAAS,SAC7C;AACI,QAAM,eAAe;AACrB,QAAM,QAAQ,aAAa;AAI3B,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,aAAa;AAEjC,OAAK,YAAY,eAAe,YAAY,cAAc,MAAM,YAAY,WAAW,YAAY,kBAAkB,GACrH;AACI,WAAO;AAAA,EACX;AAEA,QAAM,KAAK,IAAI,UAAU,UAAU,GAAG,MAAM,SAAS,MAAM,QAAQ;AACnE,QAAM,SAAS,aAAa,IAAI,IAAI,aAAa,WAAW;AAE5D,SAAO;AACX;AAEA,IAAM,oBAAN,MACA;AAAA,EACI,YAAY,QAAQ,MAAM,MAAM,MAAM,SAAS,MAAM,cAAc,MACnE;AACI,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EAEvB;AACJ;AAgBO,SAAS,oBAAoB,SAAS,MAAM,QAAQ,KAAK,SAChE;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,IAAI,CAAC;AAEnC,QAAM,eAAe,IAAI,kBAAkB,OAAO,KAAK,QAAQ,OAAO;AAEtE,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,wBAAoB,MAAM,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO,UAAU,mBAAmB,YAAY;AAAA,EACzG;AAEJ;AAEA,SAAS,oBAAoB,SAAS,SAAS,SAC/C;AAGI,QAAM,eAAe;AACrB,QAAM,QAAQ,aAAa;AAG3B,QAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,aAAa;AAEjC,OAAK,YAAY,eAAe,YAAY,cAAc,MAAM,YAAY,WAAW,YAAY,kBAAkB,GACrH;AACI,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AAErD,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,aAAa;AAC5B,QAAM,SAAS,yBAAyB,KAAK;AAC7C,QAAM,aAAa,aAAa;AAChC,QAAM,aAAa;AACnB,QAAM,WAAW;AAEjB,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,MAAI,OAAO,WAAW,GACtB;AACI,WAAO;AAAA,EACX;AAEA,QAAM,KAAK,IAAI,UAAU,MAAM,KAAK,GAAG,MAAM,SAAS,MAAM,QAAQ;AACpE,QAAM,SAAS,aAAa,IAAI,IAAI,aAAa,WAAW;AAE5D,SAAO;AACX;AAkBO,SAAS,sBAAsB,SAAS,QAAQ,WAAW,QAAQ,KAAK,SAC/E;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,UAAU,CAAC,CAAC;AAC1C,UAAQ,OAAO,cAAc,UAAU,CAAC,CAAC;AAEzC,QAAM,OAAO,oBAAoB,QAAQ,SAAS;AAClD,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,QAAQ,YAAY,OAAO,QAAQ,GAAG,OAAO,MAAM;AAChE,eAAa,YAAY;AACzB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,wBAAoB,MAAM,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO,UAAU,qBAAqB,YAAY;AAAA,EAC3G;AACJ;AAkBO,SAAS,uBAAuB,SAAS,SAAS,WAAW,QAAQ,KAAK,SACjF;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,UAAU,CAAC,CAAC;AAC1C,UAAQ,OAAO,cAAc,UAAU,CAAC,CAAC;AAEzC,QAAM,OAAO,qBAAqB,SAAS,SAAS;AACpD,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,QAAQ,YAAY,QAAQ,QAAQ,GAAG,QAAQ,MAAM;AAClE,eAAa,YAAY;AACzB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,wBAAoB,MAAM,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO,UAAU,qBAAqB,YAAY;AAAA,EAC3G;AACJ;AAgBO,SAAS,uBAAuB,SAAS,SAAS,WAAW,QAAQ,KAAK,SACjF;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,UAAU,CAAC,CAAC;AAC1C,UAAQ,OAAO,cAAc,UAAU,CAAC,CAAC;AAEzC,QAAM,OAAO,qBAAqB,SAAS,SAAS;AACpD,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,QAAQ,YAAY,QAAQ,UAAU,QAAQ,OAAO,QAAQ,MAAM,GAChF,aAAa,YAAY;AACzB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,wBAAoB,MAAM,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO,UAAU,qBAAqB,YAAY;AAAA,EAC3G;AACJ;AAEA,SAAS,gBAAgB,OAAO,SAAS,SAAS,SAClD;AAGI,QAAM,eAAe;AACrB,QAAM,QAAQ,aAAa;AAG3B,QAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,aAAa;AAEjC,OAAK,YAAY,eAAe,YAAY,cAAc,MAAM,YAAY,WAAW,YAAY,kBAAkB,GACrH;AACI,WAAO,MAAM;AAAA,EACjB;AAEA,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAM,SAAS,eAAe,OAAO,OAAO,SAAS;AAErD,MAAI,OAAO,KACX;AACI,UAAM,KAAK,IAAI,UAAU,UAAU,GAAG,MAAM,SAAS,MAAM,QAAQ;AACnE,UAAM,WAAW,aAAa,IAAI,IAAI,OAAO,OAAO,OAAO,QAAQ,OAAO,UAAU,aAAa,WAAW;AAG5G,QAAI,YAAY,KAAO,YAAY,GACnC;AACI,mBAAa,WAAW;AAAA,IAC5B;AAEA,WAAO;AAAA,EACX;AAEA,SAAO,MAAM;AACjB;AAiBO,SAAS,gBAAgB,SAAS,QAAQ,aAAa,QAAQ,KAAK,SAC3E;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,UAAQ,OAAO,eAAe,WAAW,CAAC;AAE1C,QAAM,QAAQ,IAAI,eAAe;AACjC,QAAM,SAAS;AACf,QAAM,cAAc;AACpB,QAAM,cAAc;AAEpB,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,WAAW;AACxB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,0BAAsB,MAAM,WAAW,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,iBAAiB,YAAY;AAEtG,QAAI,aAAa,aAAa,GAC9B;AACI;AAAA,IACJ;AAEA,UAAM,cAAc,aAAa;AAAA,EACrC;AACJ;AAGA,SAAS,oBAAoB,SAAS,OAAO,QAAQ,UAAU,SAC/D;AACI,QAAM,YAAY;AAClB,YAAU,UAAU;AACpB,YAAU,QAAQ;AAClB,YAAU,SAAS;AACnB,YAAU,WAAW;AACrB,YAAU,MAAM;AAEhB,SAAO;AACX;AAkBO,SAAS,uBAAuB,SAAS,QAAQ,aAAa,QACrE;AACI,QAAM,SAAS,IAAI,YAAY;AAE/B,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,eAAe,MAAM,CAAC;AACrC,UAAQ,OAAO,eAAe,WAAW,CAAC;AAE1C,QAAM,QAAQ,IAAI,eAAe;AACjC,QAAM,SAAS;AACf,QAAM,cAAc;AACpB,QAAM,cAAc;AACpB,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,WAAW;AACxB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,0BAAsB,MAAM,WAAW,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,iBAAiB,YAAY;AAEtG,QAAI,aAAa,YAAY,GAC7B;AACI,aAAO;AAAA,IACX;AAEA,UAAM,cAAc,aAAa;AAAA,EACrC;AAEA,SAAO;AACX;AAEA,SAAS,kBAAkB,OAAO,SAAS,SAAS,SACpD;AACI,QAAM,eAAe;AACrB,QAAM,QAAQ,aAAa;AAG3B,QAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,aAAa;AAEjC,OAAK,YAAY,eAAe,YAAY,aAAa,MAAM,YAAY,WAAW,YAAY,iBAAiB,GACnH;AACI,WAAO,MAAM;AAAA,EACjB;AAEA,QAAM,OAAO,UAAU,OAAO,MAAM,MAAM;AAC1C,QAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAM,SAAS,iBAAiB,OAAO,OAAO,SAAS;AAEvD,MAAI,OAAO,KACX;AACI,UAAM,KAAK,IAAI,UAAU,UAAU,GAAG,MAAM,SAAS,MAAM,QAAQ;AACnE,UAAM,WAAW,aAAa,IAAI,IAAI,OAAO,OAAO,OAAO,QAAQ,OAAO,UAAU,aAAa,WAAW;AAC5G,iBAAa,WAAW;AAExB,WAAO;AAAA,EACX;AAEA,SAAO,MAAM;AACjB;AAoBO,SAAS,mBAAmB,SAAS,QAAQ,iBAAiB,aAAa,QAAQ,KAAK,SAC/F;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,gBAAgB,CAAC,CAAC;AAChD,UAAQ,OAAO,cAAc,gBAAgB,CAAC,CAAC;AAC/C,UAAQ,OAAO,eAAe,WAAW,CAAC;AAE1C,QAAM,QAAQ,IAAI,iBAAiB;AACnC,QAAM,SAAS,CAAE,iBAAiB,iBAAiB,OAAO,MAAM,CAAE;AAClE,QAAM,QAAQ;AACd,QAAM,SAAS,OAAO;AACtB,QAAM,cAAc;AACpB,QAAM,cAAc;AAEpB,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,WAAW;AACxB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,4BAAwB,MAAM,WAAW,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,mBAAmB,YAAY;AAE1G,QAAI,aAAa,YAAY,GAC7B;AACI;AAAA,IACJ;AAEA,UAAM,cAAc,aAAa;AAAA,EACrC;AACJ;AAgBO,SAAS,oBAAoB,SAAS,SAAS,iBAAiB,aAAa,QAAQ,KAAK,SACjG;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,gBAAgB,CAAC,CAAC;AAChD,UAAQ,OAAO,cAAc,gBAAgB,CAAC,CAAC;AAC/C,UAAQ,OAAO,eAAe,WAAW,CAAC;AAE1C,QAAM,QAAQ,IAAI,iBAAiB;AACnC,QAAM,SAAS,CAAE,iBAAiB,iBAAiB,QAAQ,OAAO,GAAG,iBAAiB,iBAAiB,QAAQ,OAAO,CAAE;AACxH,QAAM,QAAQ;AACd,QAAM,SAAS,QAAQ;AACvB,QAAM,cAAc;AACpB,QAAM,cAAc;AAEpB,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,WAAW;AACxB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,4BAAwB,MAAM,WAAW,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,mBAAmB,YAAY;AAE1G,QAAI,aAAa,YAAY,GAC7B;AACI;AAAA,IACJ;AAEA,UAAM,cAAc,aAAa;AAAA,EACrC;AACJ;AAeO,SAAS,oBAAoB,SAAS,SAAS,iBAAiB,aAAa,QAAQ,KAAK,SACjG;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,UAAU,KAAK;AAEpC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,UAAQ,OAAO,eAAe,gBAAgB,CAAC,CAAC;AAChD,UAAQ,OAAO,cAAc,gBAAgB,CAAC,CAAC;AAC/C,UAAQ,OAAO,eAAe,WAAW,CAAC;AAE1C,QAAM,QAAQ,IAAI,iBAAiB;AACnC,QAAM,SAAS,QAAQ,SAAS,IAAI,YAAU,iBAAiB,iBAAiB,MAAM,CAAC;AACvF,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,QAAQ;AACvB,QAAM,cAAc;AACpB,QAAM,cAAc;AAEpB,QAAM,eAAe,IAAI,oBAAoB;AAC7C,eAAa,QAAQ;AACrB,eAAa,MAAM;AACnB,eAAa,SAAS;AACtB,eAAa,WAAW;AACxB,eAAa,cAAc;AAE3B,WAAS,IAAI,GAAG,IAAI,WAAW,kBAAkB,EAAE,GACnD;AACI,4BAAwB,MAAM,WAAW,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,mBAAmB,YAAY;AAE1G,QAAI,aAAa,YAAY,GAC7B;AACI;AAAA,IACJ;AAEA,UAAM,cAAc,aAAa;AAAA,EACrC;AACJ;AAYO,SAAS,4BAA4B,SAAS,KAAK,SAC1D;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAM,cAAc;AACpB,QAAM,kBAAkB;AAC5B;AAcO,SAAS,gCAAgC,SAAS,KAAK,SAC9D;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAM,kBAAkB;AACxB,QAAM,sBAAsB;AAChC;AAYO,SAAS,mBAAmB,SAAS,SAC5C;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAM,UAAU;AACpB;AAWO,SAAS,mBAAmB,SACnC;AACI,QAAM,QAAQ,iBAAiB,OAAO;AAEtC,SAAO,MAAM;AACjB;AAEA,IAAM,mBAAN,MACA;AAAA,EACI,YAAY,OAAO,UAAU,QAAQ,WACrC;AACI,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,YAAY;AAAA,EACrB;AACJ;AAEA,SAAS,kBAAkB,SAAS,SAAS,SAC7C;AAEI,QAAM,mBAAmB;AACzB,QAAM,QAAQ,iBAAiB;AAG/B,QAAM,QAAQ,MAAM,WAAW,OAAO;AAGtC,QAAM,OAAO,MAAM,UAAU,MAAM,MAAM;AAEzC,MAAI,KAAK,SAAS,WAAW,kBAC7B;AACI,WAAO;AAAA,EACX;AAEA,aAAW,OAAO,IAAI;AAEtB,MAAI,KAAK,aAAa,UAAU,aAChC;AACI,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,wBAAwB,OAAO,IAAI;AACrD,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,yBAAyB,KAAK;AAC7C,QAAM,SAAS,YAAY,CAAE,iBAAiB,QAAS,GAAG,GAAG,CAAG;AAChE,QAAM,aAAa;AACnB,QAAM,aAAa,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;AACpE,QAAM,WAAW;AAEjB,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,SAAS,gBAAgB,OAAO,OAAO,MAAM,CAAC;AAEpD,MAAI,OAAO,WAAW,iBAAiB,QACvC;AACI,WAAO;AAAA,EACX;AAEA,MAAI,eAAe,OAAO;AAE1B,MAAI,OAAO,aAAa,GACxB;AACI,UAAM,gBAAgB,mBAAmB,KAAK;AAC9C,mBAAe,iBAAiB,WAAW,aAAa;AAAA,EAC5D;AAEA,QAAM,UAAU;AAChB,QAAM,YAAY,oBAAoB,KAAK;AAC3C,QAAM,YAAY,iBAAiB,YAAY,aAAa,IAAM,UAAU,OAAO,WAAW,iBAAiB;AAC/G,QAAM,YAAY,YAAY,MAAM,cAAc,iBAAiB,QAAQ,CAAC;AAC5E,QAAM,UAAU,QAAQ,WAAW,SAAS;AAE5C,QAAM,aAAa,KAAK;AACxB,QAAM,MAAM,MAAM,eAAe,UAAU,WAAW;AACtD,UAAQ,OAAO,KAAK,cAAc,aAAa,IAAI,OAAO,KAAK;AAC/D,QAAM,QAAQ,IAAI,OAAO,KAAK,UAAU;AACxC,QAAM,UAAU,IAAI,KAAK,KAAK,UAAU;AAExC,QAAM,iBAAiB,SAAS,MAAM,gBAAgB,QAAQ,SAAS,OAAO;AAC9E,QAAM,mBAAmB,QAAQ,aAAa,QAAQ,MAAM,cAAc,QAAQ,MAAM,GAAG,OAAO;AAElG,SAAO;AACX;AAoBO,SAAS,gBAAgB,SAAS,UAAU,QAAQ,WAC3D;AACI,UAAQ,OAAO,eAAe,QAAQ,CAAC;AACvC,UAAQ,OAAO,UAAU,MAAM,KAAK,SAAS,CAAG;AAChD,UAAQ,OAAO,UAAU,SAAS,CAAC;AACnC,QAAM,QAAQ,iBAAiB,OAAO;AACtC,UAAQ,OAAO,MAAM,WAAW,KAAK;AAErC,MAAI,MAAM,QACV;AACI;AAAA,EACJ;AAEA,QAAM,mBAAmB,IAAI,iBAAiB,OAAO,UAAU,QAAQ,SAAS;AAChF,QAAM,OAAO,IAAI,OAAO,SAAS,IAAI,QAAQ,SAAS,IAAI,QAAQ,SAAS,IAAI,QAAQ,SAAS,IAAI,MAAM;AAE1G;AAAA,IACI,MAAM,WAAW,MAAM,WAAW,cAAc;AAAA,IAChD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAEA,SAAS,kBAAkB,OAAO,UAClC;AACI,MAAI,aAAa,eACjB;AACI,WAAO;AAAA,EACX;AAEA,MAAI,SAAS;AACb,MAAI,aAAa,MAAM,YAAY,QAAQ;AAE3C,SAAO,WAAW,iBAAiB,eACnC;AACI,UAAM,SAAS,MAAM,YAAY,WAAW,YAAY;AACxD,aAAS,WAAW;AACpB,iBAAa;AAAA,EACjB;AAEA,SAAO;AACX;AAEO,SAAS,UAAU,GAAG,IAC7B;AACI,UAAQ,OAAQ,KAAK,MAAM,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAG;AAC/D;AAEO,SAAS,aAAa,GAAG,GAChC;AACI,MAAI,MAAM,QAAQ,CAAC,GACnB;AAAE,YAAQ,OAAO,KAAK,KAAK,IAAI,EAAE,MAAM;AAAA,EAAG,OAE1C;AAAE,YAAQ,OAAO,KAAK,KAAK,IAAI,EAAE,KAAK;AAAA,EAAG;AAC7C;AAEO,SAAS,uBAAuB,OACvC;AACI,MAAI,CAAC,cAAc;AAAE;AAAA,EAAQ;AAE7B,QAAM,eAAe,MAAM,UAAU;AAErC,WAAS,YAAY,GAAG,YAAY,cAAc,EAAE,WACpD;AACI,UAAM,OAAO,MAAM,UAAU,SAAS;AAEtC,QAAI,KAAK,OAAO,eAChB;AAEI;AAAA,IACJ;AAEA,YAAQ,OAAO,cAAc,KAAK,EAAE;AAEpC,UAAM,eAAe,kBAAkB,OAAO,KAAK,QAAQ;AAC3D,UAAM,eAAe,KAAK;AAE1B,QAAI,aAAa,KAAK;AAEtB,WAAO,eAAe,eACtB;AACI,YAAM,YAAY,cAAc;AAChC,YAAM,YAAY,aAAa;AAE/B,YAAM,UAAU,MAAM,aAAa,SAAS;AAE5C,YAAM,YAAY,QAAQ,QAAQ,eAAe,4BAA4B;AAE7E,UAAI,aAAa,QAAQ,QAAQ,eAAe,0BAA0B,GAC1E;AACI,YAAI,iBAAiB,UAAU,cAC/B;AACI,gBAAM,kBAAkB,kBAAkB,OAAO,QAAQ,QAAQ;AACjE,kBAAQ,OAAO,oBAAoB,YAAY;AAAA,QACnD;AAAA,MACJ,OAEA;AACI,gBAAQ,OAAO,QAAQ,aAAa,aAAa;AAAA,MACrD;AAEA,mBAAa,QAAQ,MAAM,SAAS,EAAE;AAAA,IAC1C;AAEA,QAAI,WAAW,KAAK;AAEpB,WAAO,aAAa,eACpB;AACI,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,WAAW;AAE7B,YAAM,QAAQ,MAAM,WAAW,OAAO;AAEtC,YAAM,iBAAiB,YAAY;AAEnC,YAAM,YAAY,MAAM,UAAU,MAAM,MAAM,cAAc,EAAE,MAAM;AAEpE,UAAI,iBAAiB,UAAU,kBAAkB,UAAU,aAAa,UAAU,gBAClF;AACI,gBAAQ,OAAO,MAAM,aAAa,aAAa;AAAA,MACnD,WACS,iBAAiB,UAAU,cACpC;AACI,YAAI,UAAU,aAAa,UAAU,cACrC;AACI,kBAAQ,OAAO,MAAM,aAAa,aAAa;AAAA,QACnD;AAAA,MACJ,OAEA;AACI,cAAM,gBAAgB,kBAAkB,OAAO,MAAM,QAAQ;AAC7D,gBAAQ,OAAO,kBAAkB,YAAY;AAAA,MACjD;AAEA,iBAAW,MAAM,MAAM,SAAS,EAAE;AAAA,IACtC;AAAA,EACJ;AACJ;AAEO,SAAS,qBAAqB,OACrC;AACI,MAAI,CAAC,cAAc;AAAE;AAAA,EAAQ;AAE7B,MAAI,iBAAiB;AACrB,MAAI,iBAAiB;AACrB,MAAI,kBAAkB;AACtB,MAAI,oBAAoB;AACxB,MAAI,mBAAmB;AAGvB,QAAM,WAAW,MAAM,eAAe;AAEtC,WAAS,WAAW,GAAG,WAAW,UAAU,EAAE,UAC9C;AACI,UAAM,MAAM,MAAM,eAAe,QAAQ;AAEzC,QAAI,IAAI,aAAa,eACrB;AACI,wBAAkB;AAElB,UAAI,aAAa,UAAU,cAC3B;AACI,gBAAQ,OAAO,IAAI,SAAS,UAAU,CAAC;AACvC,gBAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC;AACtC,gBAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACzC,WACS,aAAa,UAAU,aAChC;AACI,gBAAQ,OAAO,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK;AAClD,gBAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACzC,WACS,aAAa,UAAU,gBAChC;AACI,gBAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC;AACtC,gBAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACzC,OAEA;AACI,gBAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACzC;AAGA;AACI,cAAM,SAAS,MAAM;AACrB,gBAAQ,OAAO,IAAI,KAAK,SAAS,CAAC;AAClC,0BAAkB,IAAI,KAAK;AAE3B,iBAAS,IAAI,GAAG,IAAI,IAAI,KAAK,OAAO,EAAE,GACtC;AACI,gBAAM,UAAU,IAAI,KAAK,KAAK,CAAC;AAE/B,gBAAM,SAAS,QAAQ;AACvB,uBAAa,QAAQ,MAAM;AAC3B,gBAAM,OAAO,OAAO,MAAM;AAC1B,kBAAQ,OAAO,KAAK,aAAa,QAAQ;AACzC,kBAAQ,OAAO,KAAK,eAAe,CAAC;AAIpC,cAAI,aAAa,UAAU,gBAC3B;AACI,oBAAQ,OAAO,KAAK,mBAAmB,aAAa;AAAA,UACxD;AAGA,cAAI,cAAc;AAClB,cAAI,UAAU,KAAK;AAEnB,iBAAO,YAAY,eACnB;AACI,sBAAU,MAAM,YAAY,OAAO;AACnC,kBAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,oBAAQ,OAAO,MAAM,gBAAgB,WAAW;AAEhD,gBAAI,aAAa,UAAU,gBAC3B;AACI,sBAAQ,OAAO,MAAM,aAAa,aAAa;AAAA,YACnD,WACS,aAAa,UAAU,cAChC;AACI,sBAAQ,OAAO,cAAc,MAAM,QAAQ,MAAM,WAAW,aAAa;AAAA,YAC7E,OAEA;AACI,oBAAM,YAAY,cAAc,MAAM,QAAQ;AAC9C,sBAAQ,OAAO,cAAc,WAAW,oBAAoB,cAAc,WAAW,cAAc;AAAA,YACvG;AAEA,0BAAc;AACd,sBAAU,MAAM;AAAA,UACpB;AAGA,cAAI,aAAa,KAAK;AAEtB,iBAAO,eAAe,eACtB;AACI,kBAAM,YAAY,cAAc;AAChC,kBAAM,YAAY,aAAa;AAE/B,yBAAa,MAAM,cAAc,SAAS;AAC1C,kBAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,oBAAQ,OAAO,QAAQ,aAAa,UAAU,YAAY;AAC1D,oBAAQ,OAAO,QAAQ,MAAM,CAAC,EAAE,WAAW,UAAU,QAAQ,MAAM,CAAC,EAAE,WAAW,MAAM;AACvF,yBAAa,QAAQ,MAAM,SAAS,EAAE;AAAA,UAC1C;AAGA,cAAI,WAAW,KAAK;AAEpB,iBAAO,aAAa,eACpB;AACI,kBAAM,UAAU,YAAY;AAG5B,kBAAM,YAAY,WAAW;AAE7B,yBAAa,MAAM,YAAY,OAAO;AACtC,kBAAM,QAAQ,MAAM,WAAW,OAAO;AAGtC,oBAAQ,OAAO,MAAM,WAAW,OAAO;AAEvC,kBAAM,iBAAiB,YAAY;AAEnC,yBAAa,MAAM,WAAW,MAAM,MAAM,cAAc,EAAE,MAAM;AAChE,kBAAM,YAAY,MAAM,UAAU,MAAM,MAAM,cAAc,EAAE,MAAM;AAEpE,gBAAI,aAAa,UAAU,kBAAkB,UAAU,aAAa,UAAU,gBAC9E;AACI,sBAAQ,OAAO,MAAM,aAAa,UAAU,cAAc;AAAA,YAC9D,WACS,aAAa,UAAU,gBAAgB,UAAU,aAAa,UAAU,cACjF;AACI,sBAAQ,OAAO,MAAM,aAAa,UAAU,YAAY;AAAA,YAC5D,WACS,aAAa,UAAU,aAChC;AACI,sBAAQ,OAAO,MAAM,aAAa,UAAU,WAAW;AAAA,YAC3D,WACS,YAAY,UAAU,qBAC/B;AACI,sBAAQ,OAAO,MAAM,aAAa,QAAQ;AAAA,YAC9C;AAEA,kBAAM,WAAW,cAAc,OAAO,KAAK;AAC3C,oBAAQ,OAAO,SAAS,YAAY,OAAO;AAC3C,oBAAQ,OAAO,SAAS,YAAY,MAAM,MAAM,CAAC,EAAE,MAAM;AACzD,oBAAQ,OAAO,SAAS,YAAY,MAAM,MAAM,CAAC,EAAE,MAAM;AAEzD,uBAAW,MAAM,MAAM,SAAS,EAAE;AAAA,UACtC;AAAA,QACJ;AAAA,MACJ;AAGA;AACI,cAAM,WAAW,MAAM;AACvB,gBAAQ,OAAO,IAAI,SAAS,SAAS,CAAC;AACtC,6BAAqB,IAAI,SAAS;AAElC,iBAAS,IAAI,GAAG,IAAI,IAAI,SAAS,OAAO,EAAE,GAC1C;AACI,gBAAM,aAAa,IAAI,SAAS,KAAK,CAAC;AACtC,kBAAQ,OAAO,KAAK,WAAW,aAAa,WAAW,YAAY,SAAS,MAAM;AAClF,gBAAM,UAAU,SAAS,WAAW,SAAS;AAE7C,cAAI,aAAa,UAAU,aAC3B;AACI,oBAAQ,OAAO,WAAW,SAAS,eAAe,MAC7C,WAAW,WAAW,kBAAkB,2BAA2B,CAAC;AAAA,UAC7E;AACA,kBAAQ,OAAO,QAAQ,aAAa,QAAQ;AAC5C,kBAAQ,OAAO,QAAQ,eAAe,aAAa;AACnD,kBAAQ,OAAO,QAAQ,eAAe,CAAC;AAAA,QAC3C;AAAA,MACJ;AAGA;AACI,cAAM,SAAS,MAAM;AACrB,gBAAQ,OAAO,IAAI,OAAO,SAAS,CAAC;AACpC,2BAAmB,IAAI,OAAO;AAE9B,iBAAS,IAAI,GAAG,IAAI,IAAI,OAAO,OAAO,EAAE,GACxC;AACI,gBAAM,WAAW,IAAI,OAAO,KAAK,CAAC;AAClC,kBAAQ,OAAO,KAAK,SAAS,WAAW,SAAS,UAAU,OAAO,MAAM;AACxE,gBAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,kBAAQ,OAAO,MAAM,aAAa,QAAQ;AAC1C,kBAAQ,OAAO,MAAM,eAAe,aAAa;AACjD,kBAAQ,OAAO,MAAM,eAAe,CAAC;AAAA,QACzC;AAAA,MACJ;AAGA;AACI,cAAM,UAAU,MAAM;AACtB,gBAAQ,OAAO,IAAI,QAAQ,SAAS,CAAC;AACrC,4BAAoB,IAAI,QAAQ;AAEhC,iBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,OAAO,EAAE,GACzC;AACI,gBAAM,YAAY,IAAI,QAAQ,KAAK,CAAC;AACpC,kBAAQ,OAAO,KAAK,UAAU,YAAY,UAAU,WAAW,QAAQ,MAAM;AAC7E,gBAAM,SAAS,QAAQ,UAAU,QAAQ;AACzC,kBAAQ,OAAO,OAAO,aAAa,QAAQ;AAC3C,kBAAQ,OAAO,OAAO,eAAe,CAAC;AAAA,QAC1C;AAAA,MACJ;AAAA,IACJ,OAEA;AACI,cAAQ,OAAO,IAAI,KAAK,UAAU,CAAC;AACnC,cAAQ,OAAO,IAAI,SAAS,UAAU,CAAC;AACvC,cAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AACrC,cAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC;AACtC,cAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,IACzC;AAAA,EACJ;AAEA,QAAM,aAAa,aAAa,MAAM,eAAe;AACrD,UAAQ,OAAO,mBAAmB,UAAU;AAE5C,QAAM,cAAc,aAAa,MAAM,UAAU;AACjD,UAAQ,OAAO,mBAAmB,WAAW;AAE7C,QAAM,gBAAgB,aAAa,MAAM,YAAY;AACrD,UAAQ,OAAO,qBAAqB,aAAa;AAGjD,WAAS,aAAa,GAAG,aAAa,oBAAoB,EAAE,YAC5D;AACI,UAAM,QAAQ,MAAM,gBAAgB,OAAO,UAAU;AAErD;AACI,YAAM,WAAW,MAAM;AACvB,cAAQ,OAAO,MAAM,SAAS,SAAS,CAAC;AACxC,2BAAqB,MAAM,SAAS;AAEpC,eAAS,IAAI,GAAG,IAAI,MAAM,SAAS,OAAO,EAAE,GAC5C;AACI,cAAM,aAAa,MAAM,SAAS,KAAK,CAAC;AACxC,qBAAa,UAAU,WAAW,SAAS;AAC3C,cAAM,UAAU,SAAS,WAAW,SAAS;AAC7C,gBAAQ,OAAO,WAAW,SAAS,aAAa,MAC3C,WAAW,YAAY,kBAAkB,wBAAwB,kBAAkB,qBAAqB,CAAC;AAC9G,gBAAQ,OAAO,QAAQ,aAAa,UAAU,WAAW;AACzD,gBAAQ,OAAO,QAAQ,eAAe,UAAU;AAChD,gBAAQ,OAAO,QAAQ,eAAe,CAAC;AAEvC,cAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,cAAM,UAAU,QAAQ,MAAM,CAAC,EAAE;AACjC,qBAAa,MAAM,WAAW,OAAO;AACrC,qBAAa,MAAM,WAAW,OAAO;AAErC,YAAI,aAAa,kBACjB;AACI,gBAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,gBAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,kBAAQ,OAAOK,UAAS,MAAM,SAAS,OAAO,OAAO,MAAM,SAAS,WAAW,cAAc;AAC7F,kBAAQ,OAAOA,UAAS,MAAM,SAAS,OAAO,OAAO,MAAM,SAAS,WAAW,cAAc;AAAA,QACjG;AAAA,MACJ;AAAA,IACJ;AAEA;AACI,YAAM,SAAS,MAAM;AACrB,cAAQ,OAAO,MAAM,OAAO,SAAS,CAAC;AACtC,yBAAmB,MAAM,OAAO;AAEhC,eAAS,IAAI,GAAG,IAAI,MAAM,OAAO,OAAO,EAAE,GAC1C;AACI,cAAM,WAAW,MAAM,OAAO,KAAK,CAAC;AACpC,qBAAa,QAAQ,SAAS,OAAO;AACrC,cAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,gBAAQ,OAAO,MAAM,aAAa,UAAU,WAAW;AACvD,gBAAQ,OAAO,MAAM,eAAe,UAAU;AAC9C,gBAAQ,OAAO,MAAM,eAAe,CAAC;AAErC,cAAM,UAAU,MAAM,MAAM,CAAC,EAAE;AAC/B,cAAM,UAAU,MAAM,MAAM,CAAC,EAAE;AAC/B,qBAAa,MAAM,WAAW,OAAO;AACrC,qBAAa,MAAM,WAAW,OAAO;AAErC,YAAI,aAAa,kBACjB;AACI,gBAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,gBAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,kBAAQ,OAAOA,UAAS,MAAM,SAAS,OAAO,OAAO,MAAM,SAAS,WAAW,cAAc;AAC7F,kBAAQ,OAAOA,UAAS,MAAM,SAAS,OAAO,OAAO,MAAM,SAAS,WAAW,cAAc;AAAA,QACjG;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,iBAAiB,aAAa,MAAM,aAAa;AACvD,UAAQ,OAAO,sBAAsB,cAAc;AACnD,UAAQ,OAAO,sBAAsB,MAAM,WAAW,QAAQ,MAAM,qBAAqB,iBAAiB,oBAAoB,MAAM,WAAW,QAAQ,IAAI,EAAE;AAE7J,QAAM,eAAe,aAAa,MAAM,WAAW;AACnD,UAAQ,OAAO,oBAAoB,YAAY;AACnD;AAEA,SAASA,UAAS,QAAQ,UAC1B;AACI,QAAM,aAAa,KAAK,MAAM,WAAW,EAAE;AAE3C,MAAI,cAAc,OAAO,YACzB;AACI,WAAO;AAAA,EACX;AAEA,UAAQ,OAAO,KAAK,UAAU,IAAK,OAAO,CAAC,KAAK,OAAO,WAAW,EAAE,OAAQ,OAAO,CAAC;AACxF;AAEO,SAAS,mBAAmB,OACnC;AACI,MAAI,CAAC,cAAc;AAAE;AAAA,EAAQ;AAE7B,QAAM,eAAe,MAAM,aAAa;AACxC,UAAQ,OAAO,gBAAgB,gBAAgB,MAAM,aAAa,CAAC;AACnE,MAAI,wBAAwB;AAE5B,WAAS,eAAe,GAAG,eAAe,cAAc,EAAE,cAC1D;AACI,UAAM,UAAU,MAAM,aAAa,YAAY;AAE/C,QAAI,QAAQ,cAAc,eAC1B;AACI;AAAA,IACJ;AAEA,YAAQ,OAAO,QAAQ,cAAc,YAAY;AAEjD,6BAAyB;AAEzB,UAAM,YAAY,QAAQ,QAAQ,eAAe,4BAA4B;AAC7E,UAAM,kBAAkB,QAAQ,QAAQ,eAAe,kCAAkC;AACzF,UAAM,YAAY,QAAQ,QAAQ,eAAe,0BAA0B;AAE3E,YAAQ,OAAO,aAAa,SAAS,mBAAmB,KAAK;AAC7D,YAAQ,OAAO,aAAa,SAAS,aAAa,KAAK;AAEvD,UAAM,QAAQ,QAAQ;AAEtB,QAAI,UAAU,UAAU,aACxB;AACI,UAAI,YAAY,aAAa,OAC7B;AACI,gBAAQ,OAAO,KAAK,QAAQ,cAAc,QAAQ,aAAa,kBAAkB;AAAA,MACrF,OAEA;AACI,gBAAQ,OAAO,QAAQ,eAAe,aAAa;AAAA,MACvD;AAAA,IACJ,WACS,SAAS,UAAU,qBAC5B;AACI,cAAQ,OAAO,aAAa,QAAQ,aAAa,KAAK;AAAA,IAC1D,OAEA;AACI,cAAQ,OAAO,aAAa,SAAS,UAAU,UAAU,cAAc;AAAA,IAC3E;AAEA,UAAM,aAAa,gBAAgB,OAAO,OAAO;AACjD,YAAQ,OAAO,WAAW,cAAc,YAAY;AACpD,YAAQ,OAAO,WAAW,aAAa,QAAQ,MAAM,CAAC,EAAE,QAAQ,OAAO;AACvE,YAAQ,OAAO,WAAW,aAAa,QAAQ,MAAM,CAAC,EAAE,MAAM;AAE9D,UAAM,eAAe,WAAW,WAAW,kBAAkB,wBAAwB;AAErF,YAAQ,OAAO,YAAY,eAAe,kBAAkB,aAAa,WAAW,QAAQ,OAAO,cAAc,OAAO,WAAW,EAAE;AACrI,YAAQ,OAAO,KAAK,WAAW,SAAS,cAAc,WAAW,SAAS,cAAc,CAAC;AAAA,EAC7F;AAEA,QAAM,iBAAiB,aAAa,MAAM,aAAa;AACvD,UAAQ,OAAO,0BAA0B,cAAc;AAC3D;;;AC57GO,IAAM,gBAAgB;AA8BtB,SAAS,qBAChB;AACI,UAAQ,KAAK,kCAAkC;AACnD;AAWO,SAAS,sBAChB;AACI,UAAQ,KAAK,mCAAmC;AACpD;AAWO,SAAS,0BAChB;AACI,UAAQ,KAAK,uCAAuC;AACxD;;;AC7BA,SAAS,SAAU,KAAK,MAAM,OAC9B;AACI,MAAI,UAAU,QACd;AACI,QAAK,IAAK,IAAI;AAEd,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEO,IAAM,eAAe,oBAAI,IAAI;AAEpC,IAAI,QAAQ;AAQL,SAAS,cAAe,OAC/B;AACI,UAAQ;AACZ;AAQO,SAAS,gBAChB;AACI,SAAO;AACX;AASO,SAAS,IAAK,QACrB;AACI,SAAO,SAAS;AACpB;AASO,SAAS,IAAK,QACrB;AACI,SAAO,SAAS;AACpB;AAUO,SAAS,QAAS,GAAG,GAC5B;AACI,SAAO,IAAI,OAAO,IAAI,OAAO,IAAI,KAAK;AAC1C;AASO,SAAS,WAAY,SAC5B;AACI,SAAO,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC;AAC3D;AAUO,SAAS,iBAAkB,SAAS,QAAQ,MACnD;AACI,MAAI,CAAC,aAAa,IAAI,OAAO,GAC7B;AACI,iBAAa,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,EACvC;AAEA,eAAa,IAAI,OAAO,EAAE,IAAI,QAAQ,IAAI;AAC9C;AAUO,SAAS,sBAAuB,SAAS,QAAQ,cAAc,OACtE;AACI,MAAI,aAAa,IAAI,OAAO,GAC5B;AACI,UAAM,WAAW,aAAa,IAAI,OAAO;AACzC,UAAM,OAAO,SAAS,IAAI,MAAM;AAEhC,QAAI,QAAQ,aACZ;AACI,YAAM,SAAS,KAAK;AACpB,oBAAc,MAAM;AAAA,IACxB;AAEA,aAAS,OAAO,MAAM;AAAA,EAC1B;AACJ;AAUO,SAAS,kBAAmB,SACnC;AACI,MAAI,aAAa,IAAI,OAAO,GAC5B;AACI,iBAAa,IAAI,OAAO,EAAE,MAAM;AAAA,EACpC;AACJ;AAWO,SAAS,kBAAmB,SAAS,QAC5C;AACI,MAAI,aAAa,IAAI,OAAO,GAC5B;AACI,WAAO,aAAa,IAAI,OAAO,EAAE,IAAI,MAAM;AAAA,EAC/C;AAEA,SAAO;AACX;AAOO,SAAS,mBAAoB,SACpC;AACI,MAAI,aAAa,IAAI,OAAO,GAC5B;AACI,iBAAa,IAAI,OAAO,EAAE,QAAQ,CAAC,MAAM,WACzC;AACI,mBAAa,MAAM,MAAM;AAAA,IAC7B,CAAC;AAAA,EACL;AACJ;AAWO,SAAS,aAAc,MAAM,QACpC;AACI,QAAM,IAAI,oBAAoB,KAAK,MAAM;AAEzC,SAAO,IAAI,EAAE,EAAE,IAAI;AACnB,SAAO,IAAI,EAAE,EAAE,EAAE,IAAI;AACrB,SAAO,WAAW,CAAC,KAAK,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAC9C;AAwBO,SAAS,YAAa,SAAS,QAAQ,MAC9C;AACI,QAAM,SAAS,QAAQ,UAAU,QAAQ,OAAO,KAAK;AACrD,QAAM,SAAS,QAAQ,UAAU,QAAQ,OAAO,KAAK;AAErD,QAAM,QAAQ;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,QAAS,OAAO,QAAQ,SAAU,GAAI,OAAO,SAAS,SAAU,CAAC;AAAA,EAC3E;AAEA,QAAM,OAAO,iBAAiB,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnD;AAAA,IACI,KAAK;AAAA,IACL,QAAQ,OAAO,GAAG,CAAC,OAAO,CAAC;AAAA,IAC3B,WAAW,OAAO,QAAQ;AAAA,EAC9B;AAEA,SAAO;AACX;AAYO,SAAS,eAAgB,SAAS,QAAQ,MACjD;AACI,QAAM,SAAS,QAAQ,UAAU,QAAQ,OAAO,KAAK;AACrD,QAAM,SAAS,QAAQ,UAAU,QAAQ,OAAO,KAAK;AAErD,QAAM,QAAQ;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,QAAS,OAAO,QAAQ,SAAU,GAAI,OAAO,SAAS,SAAU,CAAC;AAAA,EAC3E;AAEA,QAAM,OAAO,aAAa,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC;AAE/C;AAAA,IACI,KAAK;AAAA,IACL,QAAQ,OAAO,GAAG,CAAC,OAAO,CAAC;AAAA,IAC3B,WAAW,OAAO,QAAQ;AAAA,EAC9B;AAEA,SAAO;AACX;AAaO,SAAS,YAAa,MAC7B;AACI,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,kBAAkB;AAAA,EACjC;AAGA,qBAAmB;AACnB,QAAM,UAAU,cAAc,QAAQ;AAEtC,SAAO,EAAE,QAAiB;AAC9B;AAUA,IAAI,eAAe;AASZ,SAAS,UAAW,MAC3B;AACI,MAAI,gBAAgB,KAAK;AAEzB,MAAI,CAAC,eACL;AAAE,oBAAgB,IAAI;AAAA,EAAI;AAC1B,MAAI,eAAe,KAAK;AAExB,MAAI,CAAC,cACL;AAAE,mBAAe;AAAA,EAAG;AAEpB,QAAM,eAAe,gBAAgB;AACrC,iBAAe,KAAK,IAAI,eAAe,KAAK,WAAW,gBAAgB,YAAY;AAGnF,QAAM,aAAa;AACnB,MAAIC,KAAI;AAGR,MAAI,KAAK,YAAY,eACrB;AACI,IAAAA,KAAI;AAAA,EACR;AAEA,MAAI,YAAY;AAGhB,SAAO,gBAAgB,iBAAiBA,QAAO,KAAK,YAAY,eAChE;AACI,UAAM,QAAQ,YAAY,IAAI;AAC9B,iBAAa,KAAK,SAAS,eAAe,YAAY;AACtD,UAAM,MAAM,YAAY,IAAI;AAC5B,iBAAa,MAAM,SAAS;AAC5B,oBAAgB;AAAA,EACpB;AAEA,SAAO;AACX;AA+BO,SAAS,YAAa,MAC7B;AACI,QAAM,eAAe,WAAW,KAAK,mBAAmB,KAAK,gBAAgB,IAAI,KAAK;AACtF,QAAM,OAAO,KAAK,SAAS,SAAY,KAAK,OAAO,WAAW;AAC9D,QAAM,UAAU,KAAK,YAAY,SAAY,KAAK,UAAU;AAC5D,QAAM,WAAW,KAAK,aAAa,SAAY,KAAK,WAAW;AAC/D,QAAM,QAAQ,KAAK,UAAU,SAAY,KAAK,QAAQ,WAAW;AACjE,QAAM,SAAS,KAAK,WAAW,SAAY,KAAK,SAAS;AAEzD,MAAI,WAAW;AACf,MAAI,WAAW,MAAM,KAAK,mBAAmB,IAAI,OAAO,KAAK,YAAY,CAAC,CAAC;AAE3E,QAAM,YAAY,CAAC;AAEnB,WAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KACrC;AAEI,UAAM,OAAO,cAAc,EAAE,SAAS,KAAK,SAAS,MAAY,UAAoB,SAAS,IAAI,OAAO,CAAC,KAAK,aAAa,IAAI,KAAK,QAAQ,CAAC,GAAG,SAAS,IAAI,OAAO,KAAK,aAAa,IAAI,KAAK,QAAQ,CAAC,GAAG,QAAgB,SAAkB,UAAoB,YAAY,IAAI,MAAa,CAAC;AAC/R,cAAU,KAAK,IAAI;AAEnB,QAAI,KAAK,GACT;AACI,UAAI,KAAK,SACT;AACI,4BAAoB;AAAA,UAChB,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,UACd,SAAS,IAAI,OAAO,CAAC,KAAK,aAAa,GAAG,CAAC;AAAA,QAC/C,CAAC;AAAA,MACL;AAAA,IACJ,OAEA;AACI,0BAAoB;AAAA,QAChB,SAAS,KAAK;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,SAAS,KAAK;AAAA,QACd,SAAS,IAAI,OAAO,KAAK,aAAa,GAAG,CAAC;AAAA,QAC1C,SAAS,IAAI,OAAO,CAAC,KAAK,aAAa,GAAG,CAAC;AAAA,MAC/C,CAAC;AAAA,IACL;AACA,eAAW;AAGX,eAAW,MAAM,UAAU,IAAI,OAAO,cAAc,CAAC,CAAC;AAAA,EAC1D;AAEA,MAAI,KAAK,SACT;AAEI,wBAAoB;AAAA,MAChB,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,SAAS,SAAS;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,SAAS,IAAI,OAAO,KAAK,aAAa,GAAG,CAAC;AAAA,IAC9C,CAAC;AAAA,EACL;AAEA,SAAO;AACX;AA6BO,SAAS,aAAc,MAC9B;AACI,MAAI,UAAU,KAAK;AAEnB,MAAI,CAAC,SACL;AACI,cAAU,iBAAiB;AAAA,EAC/B;AACA,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAG3C,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QACL;AACI,aAAS,aAAa,KAAK,SAAS,OAAO;AAAA,EAC/C;AAEA,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,kBAAkB;AAAA,EACjC;AACA,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,SAAS,QAAQ,gBAAgB,KAAK,YAAY;AAC3D,WAAS,SAAS,QAAQ,YAAY,KAAK,QAAQ;AACnD,WAAS,UAAU,eAAe,KAAK,KAAK;AAC5C,WAAS,UAAU,wBAAwB,KAAK,QAAQ;AACxD,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,UAAU,eAAe,KAAK,WAAW;AAElD,QAAM,OAAO,IAAI,SAAS;AAC1B,WAAS,MAAM,UAAU,KAAK,MAAM;AAEpC,MAAI,KAAK,QACT;AACI,aAAS,MAAM,UAAU,KAAK,MAAM;AAAA,EACxC;AAEA,QAAM,UAAU,oBAAoB,QAAQ,UAAU,IAAI;AAE1D,SAAO,EAAE,QAAgB,SAAkB,QAAQ,KAAK;AAC5D;AA+BO,SAAS,cAAe,MAC/B;AACI,MAAI,UAAU,KAAK;AAEnB,MAAI,CAAC,SACL;AACI,cAAU,iBAAiB;AAAA,EAC/B;AACA,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAC3C,WAAS,SAAS,iBAAiB,KAAK,aAAa;AACrD,WAAS,SAAS,iBAAiB,KAAK,aAAa;AAGrD,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QACL;AACI,aAAS,aAAa,KAAK,SAAS,OAAO;AAAA,EAC/C;AAEA,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,kBAAkB;AAAA,EACjC;AACA,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,SAAS,QAAQ,gBAAgB,KAAK,YAAY;AAC3D,WAAS,SAAS,QAAQ,YAAY,KAAK,QAAQ;AACnD,WAAS,UAAU,eAAe,KAAK,KAAK;AAE5C,QAAM,UAAU,IAAI,UAAU;AAE9B,MAAI,KAAK,OACT;AACI,SAAK,SAAS,KAAK,QAAQ;AAAA,EAC/B;AAEA,MAAI,KAAK,QACT;AACI,SAAK,SAAS,KAAK,IAAI,KAAK,QAAQ,KAAK,SAAS,CAAC;AACnD,SAAK,UAAU,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,EAAE;AAC/C,SAAK,UAAU,IAAI,OAAO,GAAG,KAAK,SAAS,CAAC;AAAA,EAChD;AAEA,WAAS,SAAS,WAAW,KAAK,OAAO;AACzC,WAAS,SAAS,WAAW,KAAK,OAAO;AACzC,WAAS,SAAS,UAAU,KAAK,MAAM;AACvC,QAAM,UAAU,qBAAqB,QAAQ,UAAU,OAAO;AAE9D,SAAO,EAAE,QAAgB,SAAkB,QAAQ,QAAQ;AAC/D;AA+BO,SAAS,iBAAkB,MAClC;AACI,MAAI,UAAU,KAAK;AAEnB,MAAI,CAAC,SACL;AACI,cAAU,iBAAiB;AAAA,EAC/B;AACA,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAC3C,WAAS,SAAS,iBAAiB,KAAK,aAAa;AACrD,WAAS,SAAS,iBAAiB,KAAK,aAAa;AACrD,WAAS,SAAS,kBAAkB,KAAK,cAAc;AAGvD,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QACL;AACI,aAAS,aAAa,KAAK,SAAS,OAAO;AAAA,EAC/C;AAEA,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,kBAAkB;AAAA,EACjC;AAEA,QAAM,WAAW,KAAK;AAEtB,MAAI,UACJ;AACI,uBAAmB,QAAQ,KAAK,QAAQ;AAAA,EAC5C;AAEA,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,SAAS,QAAQ,gBAAgB,KAAK,YAAY;AAC3D,WAAS,SAAS,QAAQ,YAAY,KAAK,QAAQ;AACnD,WAAS,UAAU,eAAe,KAAK,KAAK;AAC5C,WAAS,UAAU,wBAAwB,KAAK,QAAQ;AAGxD,MAAI;AAEJ,MAAI,KAAK,gBAAgB,QACzB;AACI,QAAI,KAAK,QACT;AACI,YAAM,gBAAgB,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,UAAU,CAAC;AAAA,IACpE,OAEA;AACI,YAAM,UAAU,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC;AAAA,IAC5C;AAAA,EACJ,OAEA;AACI,UAAM,UAAU,KAAK,MAAM,KAAK,IAAI;AAAA,EACxC;AAEA,QAAM,UAAU,qBAAqB,QAAQ,UAAU,GAAG;AAE1D,SAAO,EAAE,QAAgB,SAAkB,QAAQ,IAAI;AAC3D;AAwBO,SAAS,kBAAmB,MACnC;AACI,MAAI,KAAK,QAAQ,KAAK,KAAK,QAAQ,yBACnC;AACI,YAAQ,KAAK,mDAAmD,KAAK,KAAK,IAAI;AAE9E,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,KAAK,WAAW,iBAAiB;AACjD,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAE3C,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QACL;AACI,aAAS,aAAa,KAAK,SAAS,OAAO;AAAA,EAC/C;AAEA,QAAM,WAAW,KAAK,YAAY,kBAAkB;AACpD,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,UAAU,eAAe,KAAK,KAAK;AAE5C,QAAM,WAAW,CAAC;AAClB,QAAM,YAAa,IAAI,KAAK,KAAM,KAAK;AAEvC,WAAS,IAAI,GAAG,IAAI,KAAK,OAAO,KAChC;AACI,UAAM,QAAQ,IAAI;AAClB,UAAM,IAAI,KAAK,SAAS,KAAK,IAAI,KAAK;AACtC,UAAM,IAAI,KAAK,SAAS,KAAK,IAAI,KAAK;AACtC,aAAS,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA,EAClC;AAEA,MAAI;AACJ,QAAM,OAAO,cAAc,UAAU,KAAK,KAAK;AAE/C,MAAI,KAAK,UAAU,MACnB;AACI,UAAM,QAAQ,mBAAmB,KAAK,SAAS,KAAK,MAAM;AAC1D,UAAMC,MAAK,IAAI,YAAY,KAAK,UAAU,MAAM,CAAC;AACjD,WAAO,oBAAoB,MAAM,GAAGA,GAAE;AAAA,EAC1C,OAEA;AACI,WAAO,cAAc,MAAM,CAAC;AAAA,EAChC;AAEA,QAAM,UAAU,qBAAqB,QAAQ,UAAU,IAAI;AAE3D,SAAO,EAAE,QAAgB,SAAkB,QAAQ,KAAK;AAC5D;AAwBO,SAAS,cAAe,MAC/B;AACI,MAAI,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,yBACvD;AACI,YAAQ,KAAK,mDAAmD,KAAK,SAAS,MAAM,IAAI;AAExF,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,KAAK,WAAW,iBAAiB;AACjD,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAE3C,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QACL;AACI,aAAS,aAAa,KAAK,SAAS,OAAO;AAAA,EAC/C;AAEA,QAAM,WAAW,KAAK,YAAY,kBAAkB;AACpD,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,UAAU,eAAe,KAAK,KAAK;AAE5C,MAAI;AACJ,QAAM,OAAO,cAAc,KAAK,UAAU,KAAK,SAAS,MAAM;AAE9D,MAAI,KAAK,UAAU,MACnB;AACI,UAAM,QAAQ,mBAAmB,KAAK,SAAS,KAAK,MAAM;AAC1D,UAAMA,MAAK,IAAI,YAAY,KAAK,UAAU,MAAM,CAAC;AACjD,WAAO,oBAAoB,MAAM,GAAGA,GAAE;AAAA,EAC1C,OAEA;AACI,WAAO,cAAc,MAAM,CAAC;AAAA,EAChC;AAEA,QAAM,UAAU,qBAAqB,QAAQ,UAAU,IAAI;AAE3D,SAAO,EAAE,QAAgB,SAAkB,QAAQ,KAAK;AAC5D;AA8BO,SAAS,wBAAyB,MACzC;AACI,MAAI,KAAK,SAAS,SAAS,GAC3B;AACI,YAAQ,KAAK,mDAAmD,KAAK,SAAS,MAAM,IAAI;AAExF,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,KAAK,WAAW,iBAAiB;AACjD,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAE3C,QAAM,WAAW,KAAK,YAAY,kBAAkB;AACpD,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,UAAU,eAAe,KAAK,KAAK;AAE5C,QAAM,QAAQ,CAAC;AAEf,MAAI,QAAQ,KAAK;AAEjB,MAAI,CAAC,OAAO;AAAE,YAAQ,IAAI,OAAO,GAAG,CAAC;AAAA,EAAG;AACxC,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QAAQ;AAAE,aAAS,IAAI,OAAO,GAAG,CAAC;AAAA,EAAG;AAG1C,WAAS,IAAI,GAAG,IAAI,KAAK,QAAS,CAAE,EAAE,QAAQ,IAAI,GAAG,KAAK,GAC1D;AACI,UAAM,OAAO,CAAC;AAEd,aAAS,IAAI,GAAG,IAAI,GAAG,KACvB;AACI,YAAM,QAAQ,KAAK,QAAS,CAAE,EAAG,IAAI,CAAE,IAAI;AAC3C,WAAK,KAAK,IAAI,QAAQ,KAAK,SAAU,KAAM,IAAI,OAAO,KAAK,MAAM,IAAI,KAAK,SAAU,QAAQ,CAAE,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,IAC1H;AACA,UAAM,KAAK,IAAI;AAAA,EACnB;AAGA,MAAI,OAAO;AACX,QAAM,QAAQ,UACd;AACI,QAAI,CAAC,MACL;AAEI,aAAO,cAAc;AAAA,QACjB,SAAS,KAAK;AAAA,QACd,MAAM,WAAW;AAAA,QACjB;AAAA;AAAA,QAGA,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,QACV,OAAO,WAAW;AAAA,MACtB,CAAC;AAAA,IACL,OAEA;AAEI,YAAM,OAAO,cAAc,MAAM,KAAK,MAAM;AAC5C,YAAM,OAAO,cAAc,MAAM,CAAC;AAClC,2BAAqB,KAAK,QAAQ,UAAU,IAAI;AAAA,IACpD;AAAA,EACJ,CAAC;AACL;AAQO,SAAS,0BAA2B,MAC3C;AACI,MAAI,KAAK,SAAS,SAAS,GAC3B;AACI,YAAQ,KAAK,mDAAmD,KAAK,SAAS,MAAM,IAAI;AAExF,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,KAAK,WAAW,iBAAiB;AACjD,WAAS,SAAS,QAAQ,KAAK,IAAI;AACnC,WAAS,SAAS,YAAY,KAAK,QAAQ;AAE3C,QAAM,WAAW,KAAK,YAAY,kBAAkB;AACpD,WAAS,UAAU,WAAW,KAAK,OAAO;AAC1C,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,SAAS,QAAQ,cAAc,KAAK,UAAU;AACvD,WAAS,UAAU,eAAe,KAAK,KAAK;AAE5C,MAAI,QAAQ,KAAK;AAEjB,MAAI,CAAC,OAAO;AAAE,YAAQ,IAAI,OAAO,GAAG,CAAC;AAAA,EAAG;AACxC,MAAI,SAAS,KAAK;AAElB,MAAI,CAAC,QAAQ;AAAE,aAAS,IAAI,OAAO,GAAG,CAAC;AAAA,EAAG;AAG1C,QAAM,QAAQ,CAAC;AAEf,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAChD;AACI,UAAM,OAAO,CAAC;AACd,UAAM,UAAU,KAAK,QAAS,CAAE;AAEhC,aAASC,KAAI,GAAG,KAAK,QAAQ,QAAQA,KAAI,IAAIA,MAC7C;AACI,YAAM,QAAQ,QAASA,EAAE,IAAI;AAC7B,WAAK,KAAK,IAAI,QAAQ,KAAK,SAAU,KAAM,IAAI,OAAO,KAAK,MAAM,IAAI,KAAK,SAAU,QAAQ,CAAE,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,IAC1H;AACA,UAAM,KAAK,IAAI;AAAA,EACnB;AAGA,MAAI,OAAO;AACX,QAAM,QAAQ,UACd;AACI,QAAI,CAAC,MACL;AAEI,aAAO,cAAc;AAAA,QACjB,SAAS,KAAK;AAAA,QACd,MAAM,WAAW;AAAA,QACjB;AAAA;AAAA,QAGA,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,QACV,OAAO,WAAW;AAAA,MACtB,CAAC;AAAA,IACL,OAEA;AAEI,YAAM,OAAO,cAAc,MAAM,KAAK,MAAM;AAC5C,YAAM,OAAO,cAAc,MAAM,CAAC;AAClC,2BAAqB,KAAK,QAAQ,UAAU,IAAI;AAAA,IACpD;AAAA,EACJ,CAAC;AACL;AASO,SAAS,yBAA0B,MAC1C;AACI,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,KAAK;AAEjB,iBAAe,gBAAiBC,MAChC;AACI,QACA;AACI,YAAM,WAAW,MAAM,MAAMA,IAAG;AAChC,YAAM,UAAU,MAAM,SAAS,KAAK;AACpC,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,SAAS,OAAO,gBAAgB,SAAS,UAAU;AAEzD,aAAO;AAAA,IACX,SACO,OACP;AACI,cAAQ,MAAM,sBAAsB,KAAK;AAEzC,YAAM;AAAA,IACV;AAAA,EACJ;AAEA,WAAS,gBAAiBC,MAAK,QAC/B;AACI,UAAM,kBAAkB,OAAO,iBAAiB,aAAaA,IAAG,oBAAoB;AAEpF,UAAM,iBAAiB,CAAC;AACxB,UAAM,iBAAiB,CAAC;AAGxB,aAAS,eAAgB,GAAG,GAC5B;AAEI,YAAM,UAAU;AAChB,YAAM,OAAO,eAAe;AAE5B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK,GAC/B;AACI,YAAI,KAAK,IAAI,eAAgB,CAAE,IAAI,CAAC,IAAI,WACpC,KAAK,IAAI,eAAgB,IAAI,CAAE,IAAI,CAAC,IAAI,SAC5C;AACI,iBAAO,IAAI;AAAA,QACf;AAAA,MACJ;AAGA,qBAAe,KAAK,GAAG,CAAC;AAExB,aAAO,OAAO;AAAA,IAClB;AAGA,UAAM,KAAK,eAAe,EAAE,QAAQ,aACpC;AACI,YAAM,UAAU,QAAQ,YACnB,KAAK,EACL,MAAM,QAAQ,EACd,IAAI,MAAM;AAGf,YAAM,mBAAmB,CAAC;AAE1B,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,GACzC;AACI,cAAM,cAAc,eAAe,QAAS,CAAE,GAAG,QAAS,IAAI,CAAE,CAAC;AACjE,yBAAiB,KAAK,WAAW;AAAA,MACrC;AACA,qBAAe,KAAK,gBAAgB;AAAA,IACxC,CAAC;AAED,WAAO;AAAA,MACH,UAAU;AAAA;AAAA,MACV,SAAS;AAAA;AAAA,IACb;AAAA,EACJ;AAEA,WAAS,eAAgB,UACzB;AAGI,WAAO,0BAA0B;AAAA,MAC7B,GAAG;AAAA,MACH,SAAS,SAAS;AAAA,MAClB,UAAU,SAAS;AAAA,IACvB,CAAC;AAAA,EACL;AAEA,SAAO,IAAI,QAAQ,OAAO,SAAS,WACnC;AACI,QACA;AACI,YAAM,SAAS,MAAM,gBAAgB,GAAG;AACxC,YAAM,WAAW,gBAAgB,KAAK,MAAM;AAC5C,YAAM,SAAS,eAAe,QAAQ;AACtC,cAAQ,MAAM;AAAA,IAClB,SACO,OACP;AACI,cAAQ,MAAM,UAAU,KAAK;AAC7B,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AA6BO,SAAS,oBAAqB,MACrC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,mBAAmB;AAAA,EACtC;AACA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAE/C,WAAS,UAAU,cAAc,KAAK,UAAU;AAChD,WAAS,UAAU,cAAc,KAAK,UAAU;AAChD,WAAS,UAAU,eAAe,KAAK,WAAW;AAElD,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,UAAU,cAAc,KAAK,UAAU;AAChD,WAAS,UAAU,kBAAkB,KAAK,cAAc;AAExD,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,SAAS,KAAK,KAAK;AACtC,WAAS,UAAU,gBAAgB,KAAK,YAAY;AAEpD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAC5D,WAAS,UAAU,YAAY,KAAK,QAAQ;AAE5C,QAAM,UAAU,sBAAsB,KAAK,SAAS,QAAQ;AAE5D,SAAO,EAAE,QAAiB;AAC9B;AAsBO,SAAS,gBAAiB,MACjC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,eAAe;AAAA,EAClC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAE/C,QAAM,OAAO,mBAAmB,KAAK,OAAO;AAC5C,QAAM,OAAO,mBAAmB,KAAK,OAAO;AAC5C,WAAS,iBAAiB,gBAAgB,MAAM,IAAI;AACpD,WAAS,UAAU,kBAAkB,KAAK,cAAc;AAExD,WAAS,UAAU,gBAAgB,KAAK,KAAK;AAC7C,WAAS,UAAU,uBAAuB,KAAK,YAAY;AAE3D,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,kBAAkB,KAAK,SAAS,QAAQ;AAExD,SAAO,EAAE,QAAiB;AAC9B;AA0BO,SAAS,oBAAqB,MACrC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,mBAAmB;AAAA,EACtC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAE/C,WAAS,UAAU,UAAU,KAAK,MAAM;AACxC,WAAS,UAAU,aAAa,KAAK,SAAS;AAC9C,WAAS,UAAU,aAAa,KAAK,SAAS;AAE9C,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,SAAS,KAAK,KAAK;AACtC,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,eAAe,KAAK,WAAW;AAElD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,sBAAsB,KAAK,SAAS,QAAQ;AAE5D,SAAO,EAAE,QAAiB;AAC9B;AA6BO,SAAS,iBAAkB,MAClC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,gBAAgB;AAAA,EACnC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAE/C,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,cAAc,KAAK,IAAI;AAC1C,WAAS,UAAU,SAAS,KAAK,KAAK;AACtC,WAAS,UAAU,gBAAgB,KAAK,YAAY;AAEpD,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAC5D,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,UAAU,kBAAkB,KAAK,cAAc;AACxD,WAAS,UAAU,cAAc,KAAK,UAAU;AAEhD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,mBAAmB,KAAK,SAAS,QAAQ;AAEzD,SAAO,EAAE,QAAiB;AAC9B;AA8BO,SAAS,qBAAsB,MACtC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,oBAAoB;AAAA,EACvC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,gBAAgB,KAAK,OAAO;AAC/C,WAAS,UAAU,cAAc,KAAK,IAAI;AAE1C,WAAS,UAAU,kBAAkB,KAAK,cAAc;AAExD,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,SAAS,KAAK,KAAK;AACtC,WAAS,UAAU,gBAAgB,KAAK,YAAY;AAEpD,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAC5D,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,WAAS,UAAU,eAAe,KAAK,WAAW;AAClD,WAAS,UAAU,iBAAiB,KAAK,aAAa;AACtD,WAAS,UAAU,cAAc,KAAK,UAAU;AAEhD,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,uBAAuB,KAAK,SAAS,QAAQ;AAE7D,SAAO,EAAE,QAAiB;AAC9B;AA4BO,SAAS,iBAAkB,MAClC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,gBAAgB;AAAA,EACnC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AAExB,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,YAAY,KAAK,QAAQ;AAC5C,WAAS,UAAU,iBAAiB,KAAK,aAAa;AACtD,WAAS,UAAU,aAAa,KAAK,SAAS;AAC9C,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,mBAAmB,KAAK,SAAS,QAAQ;AAEzD,SAAO,EAAE,QAAiB;AAC9B;AAsBO,SAAS,iBAAkB,MAClC;AACI,UAAQ,OAAO,KAAK,WAAW,MAAS;AACxC,UAAQ,OAAO,KAAK,WAAW,UAAa,KAAK,WAAW,MAAS;AAErE,MAAI,WAAW,KAAK;AAEpB,MAAI,CAAC,UACL;AACI,eAAW,IAAI,gBAAgB;AAAA,EACnC;AAEA,WAAS,UAAU,KAAK;AACxB,WAAS,UAAU,KAAK;AAExB,WAAS,UAAU,UAAU,KAAK,MAAM;AACxC,WAAS,UAAU,SAAS,KAAK,KAAK;AACtC,WAAS,UAAU,gBAAgB,KAAK,YAAY;AACpD,WAAS,UAAU,YAAY,KAAK,QAAQ;AAE5C,WAAS,UAAU,oBAAoB,KAAK,gBAAgB;AAE5D,QAAM,UAAU,mBAAmB,KAAK,SAAS,QAAQ;AAEzD,SAAO,EAAE,QAAiB;AAC9B;;;AC9hDA,IAAMC,MAAK,IAAI,OAAO;AACtB,IAAM,iBAAiB;AAsBhB,SAAS,gBAAgB,QAAQ,KAAK,QAAQ,IACrD;AACI,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,MAAI,QAAQ;AAER,QAAS,eAAT,WAAwB;AAEpB,UAAI,OAAO,aAAa,OAAO,aAAa;AAExC,eAAO,OAAO,QAAQ;AACtB,eAAO,OAAO,SAAS;AAAA,MAC3B,OAAO;AAEH,eAAO,OAAO,QAAQ;AACtB,eAAO,OAAO,SAAS;AAAA,MAC3B;AAEA,YAAM,MAAM,OAAO;AAEnB,aAAO,QAAQ,OAAO;AACtB,aAAO,SAAS,OAAO;AAEvB,aAAO,MAAM,QAAQ,OAAO;AAC5B,aAAO,MAAM,SAAS,OAAO;AAE7B,UAAI,MAAM,KAAK,GAAG;AAAA,IACtB;AAEA,WAAO,iBAAiB,UAAU,YAAY;AAE9C,iBAAa;AAAA,EACjB;AAEA,QAAM,OAAO,IAAI,YAAY;AAE7B,MAAI,gBAAgB;AAChB,SAAK,cAAc,MAAM;AAAE;AAAA,IAAQ;AACnC,SAAK,aAAa,MAAM;AAAE;AAAA,IAAQ;AAClC,SAAK,YAAY,MAAM;AAAE;AAAA,IAAQ;AACjC,SAAK,cAAc,MAAM;AAAE;AAAA,IAAQ;AACnC,SAAK,mBAAmB,MAAM;AAAE;AAAA,IAAQ;AACxC,SAAK,kBAAkB,MAAM;AAAE;AAAA,IAAQ;AACvC,SAAK,mBAAmB,MAAM;AAAE;AAAA,IAAQ;AACxC,SAAK,cAAc,MAAM;AAAE;AAAA,IAAQ;AACnC,SAAK,mBAAmB,MAAM;AAAE;AAAA,IAAQ;AACxC,SAAK,kBAAkB,MAAM;AAAE;AAAA,IAAQ;AACvC,SAAK,mBAAmB,MAAM;AAAE;AAAA,IAAQ;AACxC,SAAK,aAAa,MAAM;AAAE;AAAA,IAAQ;AAClC,SAAK,gBAAgB,MAAM;AAAE;AAAA,IAAQ;AACrC,WAAO;AAAA,EACX;AAEA,OAAK,cAAc,SAASC,KAAI,IAAI,IAAI,KAAKC,MAAK;AAC9C,IAAAA,KAAI,UAAU;AAEd,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAGV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAG7C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AACzB,0BAAqBD,KAAI,GAAG,CAAC,GAAGD,GAAG;AACnC,MAAAA,IAAG,IAAI,CAACA,IAAG;AAEX,UAAI,MAAM,QAAQA,IAAG;AACrB,UAAI,MAAM,QAAQA,IAAG;AAErB,UAAI,KAAK,MAAM;AACf,UAAI,KAAK,MAAM;AAEf,UAAI,MAAM,GAAG;AACT,QAAAE,KAAI,OAAO,IAAI,EAAE;AAAA,MACrB,OAAO;AACH,QAAAA,KAAI,OAAO,IAAI,EAAE;AAAA,MACrB;AAAA,IACJ;AAEA,IAAAA,KAAI,UAAU;AACd,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,mBAAmB,SAASD,KAAI,OAAOC,MAAK;AAC7C,QAAI,OAAO,mBAAmB,OAAOD,GAAE;AAEvC,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAE7C,UAAM,UAAUA,IAAG,EAAE;AACrB,UAAM,UAAUA,IAAG,EAAE;AACrB,UAAM,eAAe,QAAQ;AAC7B,UAAM,eAAe,QAAQ;AAC7B,QAAI,qBAAqB,eAAe;AACxC,QAAI,qBAAqB,eAAe;AACxC,yBAAqB,CAAC;AAGtB,IAAAC,KAAI,KAAK;AAGT,IAAAA,KAAI,UAAU,oBAAoB,kBAAkB;AAIpD,UAAM,QAAQ,CAAC,KAAK,MAAMD,IAAG,EAAE,GAAGA,IAAG,EAAE,CAAC;AACxC,IAAAC,KAAI,OAAO,KAAK;AAGhB,UAAM,QAAQ,MAAM;AACpB,UAAM,aAAa,MAAM,cAAc,IAAI,OAAO,GAAG,CAAC;AACtD,UAAM,cAAc,MAAM,eAAe,IAAI,OAAO,GAAG,CAAC;AACxD,QAAI,YAAY,KAAK,cAAc,KAAK;AACxC,QAAI,aAAa,KAAK,cAAc,KAAK;AACzC,UAAM,cAAc,YAAY;AAEhC,QAAI,cAAc,GAAG;AACjB,oBAAc,QAAQ,WAAW;AACjC,kBAAY,aAAa,cAAc,WAAW;AAAA,IACtD,OAAO;AACH,mBAAa,QAAQ,WAAW;AAChC,mBAAa,YAAY,cAAc,WAAW;AAAA,IACtD;AAGA,IAAAA,KAAI;AAAA,MAAU;AAAA,MACV,MAAM,UAAU;AAAA,MAAa,MAAM,UAAU;AAAA,MAC7C,MAAM,UAAU;AAAA,MAAa,MAAM,UAAU;AAAA,MAC7C,CAAC,YAAY,IAAI,YAAY,YAAY;AAAA,MAAG,CAAC,aAAa,IAAI,aAAa,YAAY;AAAA,MACvF;AAAA,MAAW;AAAA,IACf;AAGA,IAAAA,KAAI,QAAQ;AAAA,EAChB;AAEA,OAAK,mBAAmB,SAASD,KAAI,IAAI,IAAI,KAAK,KAAKC,MAAK;AACxD,IAAAA,KAAI,UAAU;AAEd,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAGV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAG7C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AACzB,0BAAqBD,KAAI,GAAG,CAAC,GAAGD,GAAG;AACnC,MAAAA,IAAG,IAAI,CAACA,IAAG;AAEX,UAAI,MAAM,QAAQA,IAAG;AACrB,UAAI,MAAM,QAAQA,IAAG;AAErB,UAAI,KAAK,MAAM;AACf,UAAI,KAAK,MAAM;AAEf,UAAI,MAAM,GAAG;AACT,QAAAE,KAAI,OAAO,IAAI,EAAE;AAAA,MACrB,OAAO;AACH,QAAAA,KAAI,OAAO,IAAI,EAAE;AAAA,MACrB;AAAA,IACJ;AAEA,IAAAA,KAAI,UAAU;AAEd,IAAAA,KAAI,YAAY,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAC3C,IAAAA,KAAI,KAAK;AAET,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY,MAAM;AACtB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,aAAa,SAAS,QAAQ,KAAK,KAAKA,MAAK;AAC9C,IAAAA,KAAI,UAAU;AACd,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAEV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAI7C,UAAM,eAAe,QAAQ;AAC7B,UAAM,eAAe,QAAQ;AAE7B,QAAI,qBAAqB,eAAe;AACxC,QAAI,qBAAqB,eAAe;AACxC,yBAAqB,CAAC;AAGtB,IAAAA,KAAI,IAAI,oBAAoB,oBAAoB,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE;AAC3E,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,kBAAkB,SAASD,KAAI,KAAK,OAAOC,MAAK;AACjD,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAG7C,UAAM,UAAUD,IAAG,EAAE;AACrB,UAAM,UAAU,CAACA,IAAG,EAAE;AAEtB,UAAM,eAAe,QAAQ;AAC7B,UAAM,eAAe,QAAQ;AAE7B,QAAI,qBAAqB,eAAe;AACxC,QAAI,qBAAqB,eAAe;AACxC,yBAAqB,CAAC;AAGtB,IAAAC,KAAI,KAAK;AAGT,IAAAA,KAAI,UAAU,oBAAoB,kBAAkB;AAKpD,UAAM,QAAQ,CAAC,KAAK,MAAMD,IAAG,EAAE,GAAGA,IAAG,EAAE,CAAC;AACxC,IAAAC,KAAI,OAAO,KAAK;AAGhB,UAAM,QAAQ,MAAM;AACpB,UAAM,aAAa,MAAM,cAAc,IAAI,OAAO,GAAG,CAAC;AACtD,UAAM,cAAc,MAAM,eAAe,IAAI,OAAO,GAAG,CAAC;AACxD,UAAM,cAAc,MAAM,QAAQ,MAAM;AACxC,QAAI,WAAW;AAEf,QAAI,cAAc,GAAG;AACjB,mBAAa,MAAM,IAAI,QAAQ,WAAW;AAC1C,kBAAY,aAAa,cAAc,WAAW;AAAA,IACtD,OAAO;AACH,kBAAY,MAAM,IAAI,QAAQ,WAAW;AACzC,mBAAa,YAAY,cAAc,WAAW;AAAA,IACtD;AAGA,IAAAA,KAAI,UAAU,OAAO,CAAC,YAAY,IAAI,YAAY,YAAY,GAAG,CAAC,aAAa,IAAI,aAAa,YAAY,GAAG,WAAW,UAAU;AAGpI,IAAAA,KAAI,QAAQ;AAAA,EAChB;AAEA,OAAK,kBAAkB,SAASD,KAAI,KAAK,KAAKC,MAAK;AAC/C,IAAAA,KAAI,UAAU;AACd,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAEV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAI7C,UAAM,UAAUD,IAAG,EAAE;AACrB,UAAM,UAAU,CAACA,IAAG,EAAE;AAEtB,UAAM,eAAe,QAAQ;AAC7B,UAAM,eAAe,QAAQ;AAE7B,QAAI,qBAAqB,eAAe;AACxC,QAAI,qBAAqB,eAAe;AAGxC,IAAAC,KAAI,IAAI,oBAAoB,oBAAoB,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE;AAC3E,IAAAA,KAAI,YAAY,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAC3C,IAAAA,KAAI,KAAK;AACT,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,mBAAmB,SAASC,KAAIC,KAAI,QAAQ,OAAOF,MAAK;AACzD,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAE7C,UAAM,KAAK,SAAS;AAGpB,UAAM,MAAMC;AACZ,UAAM,MAAMC;AACZ,QAAI,IAAI,CAAC,IAAI;AACb,QAAI,IAAI,CAAC,IAAI;AACb,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,QAAQ,IAAI;AAC9B,QAAI,iBAAiB,YAAY;AACjC,QAAI,iBAAiB,YAAY;AACjC,QAAI,iBAAiB,YAAY;AACjC,QAAI,iBAAiB,YAAY;AAGjC,QAAI,KAAK,iBAAiB;AAC1B,QAAI,KAAK,iBAAiB;AAC1B,QAAI,QAAQ,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAGxC,IAAAF,KAAI,KAAK;AAET,IAAAA,KAAI,UAAU,iBAAiB,KAAK,GAAG,iBAAiB,KAAK,CAAC;AAC9D,IAAAA,KAAI,OAAO,QAAQ,KAAK,KAAK,CAAC;AAG9B,UAAM,QAAQ,MAAM;AACpB,UAAM,aAAa,MAAM,cAAc,IAAI,OAAO,GAAG,CAAC;AACtD,UAAM,cAAc,MAAM,eAAe,IAAI,OAAO,GAAG,CAAC;AACxD,UAAM,cAAc,MAAM,QAAQ,MAAM;AACxC,UAAM,UAAU;AAChB,QAAI,cAAc,SAAS,KAAK,KAAK,UAAU,WAAW;AAC1D,QAAI,YAAa,KAAK,IAAK,UAAU,KAAK,IAAI,WAAW,CAAC;AAG1D,IAAAA,KAAI,MAAM,KAAK,KAAK,WAAW,CAAC,GAAG,CAAC;AAGpC,IAAAA,KAAI;AAAA,MAAU;AAAA,MACV,MAAM,UAAU;AAAA,MAAa,MAAM,UAAU;AAAA,MAC7C,MAAM,UAAU;AAAA,MAAa,MAAM,UAAU;AAAA,MAC7C,CAAC,YAAY,IAAI,YAAY,YAAY;AAAA,MAAG,CAAC,aAAa,IAAI,aAAa,YAAY;AAAA,MACvF;AAAA,MAAW;AAAA,IAAU;AAGzB,IAAAA,KAAI,QAAQ;AAAA,EAChB;AAEA,OAAK,mBAAmB,SAASC,KAAIC,KAAI,QAAQ,KAAKF,MAAK;AACvD,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAEV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAK7C,UAAM,MAAMC;AACZ,UAAM,MAAMC;AACZ,QAAI,IAAI,CAAC,IAAI;AACb,QAAI,IAAI,CAAC,IAAI;AAEb,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,QAAQ,IAAI;AAE9B,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,QAAQ,IAAI;AAE9B,QAAI,iBAAiB,YAAY;AACjC,QAAI,iBAAiB,YAAY;AAEjC,QAAI,iBAAiB,YAAY;AACjC,QAAI,iBAAiB,YAAY;AAGjC,QAAI,KAAK,iBAAiB;AAC1B,QAAI,KAAK,iBAAiB;AAC1B,QAAI,QAAQ,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAGxC,IAAAF,KAAI,KAAK;AACT,IAAAA,KAAI,UAAU,gBAAgB,cAAc;AAC5C,IAAAA,KAAI,OAAO,KAAK;AAEhB,IAAAA,KAAI,UAAU;AAGd,IAAAA,KAAI,IAAI,GAAG,GAAG,SAAS,OAAO,KAAK,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC;AACvD,IAAAA,KAAI,OAAO,QAAQ,CAAC,SAAS,KAAK;AAClC,IAAAA,KAAI,IAAI,QAAQ,GAAG,SAAS,OAAO,CAAC,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC;AAC5D,IAAAA,KAAI,OAAO,GAAG,SAAS,KAAK;AAC5B,IAAAA,KAAI,UAAU;AAGd,IAAAA,KAAI,YAAY,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAC3C,IAAAA,KAAI,KAAK;AAGT,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAEX,IAAAA,KAAI,QAAQ;AAAA,EAChB;AAEA,OAAK,cAAc,SAASC,KAAIC,KAAI,KAAKF,MAAK;AAC1C,IAAAA,KAAI,UAAU;AACd,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAEV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAK7C,UAAM,MAAMC;AACZ,UAAM,MAAMC;AAEZ,QAAI,IAAI,CAAC,IAAI;AACb,QAAI,IAAI,CAAC,IAAI;AAGb,UAAM,MAAO,QAAQ,IAAI,IAAK;AAC9B,UAAM,MAAO,QAAQ,IAAI,IAAK;AAE9B,UAAM,MAAO,QAAQ,IAAI,IAAK;AAC9B,UAAM,MAAO,QAAQ,IAAI,IAAK;AAE9B,IAAAF,KAAI,OAAO,KAAK,GAAG;AACnB,IAAAA,KAAI,OAAO,KAAK,GAAG;AAEnB,IAAAA,KAAI,cAAc,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAC7C,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,YAAY,SAAS,GAAG,GAAG,QAAQ,KAAKA,MAAK;AAC9C,UAAM,IAAK,OAAO,KAAM;AACxB,UAAM,IAAK,OAAO,IAAK;AACvB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI;AAEV,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAC7C,UAAM,MAAM,QAAQ,KAAK,KAAK,eAAe;AAM7C,QAAI,CAAC;AAGL,UAAM,KAAM,QAAQ,IAAK;AACzB,UAAM,KAAM,QAAQ,IAAK;AAGzB,IAAAA,KAAI,UAAU;AACd,IAAAA,KAAI,IAAI,IAAI,IAAI,QAAQ,GAAG,IAAI,KAAK,EAAE;AACtC,IAAAA,KAAI,YAAY,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAC3C,IAAAA,KAAI,KAAK;AAGT,IAAAA,KAAI,cAAc,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACtC,IAAAA,KAAI,YAAY;AAChB,IAAAA,KAAI,OAAO;AAAA,EACf;AAEA,OAAK,cAAc,SAAS,GAAG,GAAG;AAE9B,SAAK,eAAe,IAAI,OAAO,IAAI;AACnC,SAAK,eAAe,IAAI,IAAI,OAAO;AAAA,EACvC;AAEA,OAAK,UAAU;AAEf,SAAO;AACX;AAcO,SAAS,IAAI,UACpB;AACI,MAAI,WAAW;AACf,MAAI,YAAY;AAEhB,MAAI,aAAa;AACjB,MAAI,oBAAoB;AACxB,MAAI,aAAa;AAEjB,WAAS,OAAO,aAChB;AACI,0BAAsB,MAAM;AAE5B,QAAI,aAAa,GAAG;AAChB,iBAAW;AAAA,IACf;AACA,UAAM,YAAY,KAAK,KAAK,cAAc,YAAY,KAAM,IAAI,EAAE;AAClE,eAAW;AACX,iBAAa;AAEb,aAAS,WAAW,WAAW,UAAU;AAEzC;AACA,QAAI,cAAc,qBAAqB,KAAM;AACzC,mBAAa,KAAK,MAAO,aAAa,OAAS,cAAc,kBAAkB;AAC/E,mBAAa;AACb,0BAAoB;AAAA,IACxB;AAAA,EACJ;AAEA,wBAAsB,MAAM;AAChC;AAOA,SAAS,aAAa,UACtB;AACI,SAAO,IAAI,QAAQ,CAAC,SAAS,WAC7B;AACI,UAAM,MAAM,IAAI,MAAM;AACtB,QAAI,SAAS,MAAM,QAAQ,GAAG;AAC9B,QAAI,UAAU,CAAC,UACf;AACI,YAAM,eAAe;AAAA,QACjB,SAAS;AAAA,QACT,KAAK;AAAA,QACL;AAAA,MACJ;AACA,aAAO,IAAI,MAAM,KAAK,UAAU,cAAc,MAAM,CAAC,CAAC,CAAC;AAAA,IAC3D;AACA,QAAI,MAAM;AAAA,EACd,CAAC;AACL;AAmBO,SAAS,YAAY,SAAS,QAAQ,MAAM,SAAS,aAAa,MAAM,YAAY,MAAM,iBAAiB,MAAM,aAAa,MACrI;AACI,QAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAM,SAAS,CAAC;AAChB,mBAAiB,QAAQ,MAAM;AAC/B,QAAM,QAAQ,MAAM,WAAW,OAAO,OAAO,SAAS,CAAC,EAAE,SAAS,CAAC;AACnE,QAAM,cAAc;AACpB,QAAM,aAAa;AACnB,QAAM,YAAY,IAAI,OAAO,eAAe,GAAG,eAAe,GAAG,WAAW,GAAG,WAAW,CAAC;AAE3F,QAAM,WAAW,OAAO,MAAM;AAC9B,eAAa,QAAQ,EAChB,KAAK,CAAC,gBACP;AACI,UAAM,QAAQ;AAAA,EAClB,CAAC,EACA,MAAM,CAAC,UACR;AACI,YAAQ,MAAM,8BAA8B,KAAK;AAAA,EACrD,CAAC;AACL,SAAO;AACX;AAOA,SAAS,cAAc,QAAQ,IAC/B;AACI,QAAM,OAAO,OAAO,sBAAsB;AAE1C,SAAO;AAAA,IACH,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IAC7B,GAAG,KAAO,GAAG,IAAI,KAAK,OAAO,KAAK;AAAA,EACtC;AACJ;AAcO,SAAS,qBAAqB,QAAQ,WAAW,IACxD;AACI,QAAM,IAAI,OAAO;AACjB,QAAM,IAAI,OAAO;AACjB,MAAI,KAAK,cAAc,QAAQ,EAAE;AACjC,MAAI,QAAQ,IAAI;AAChB,MAAI,SAAS,IAAI,OAAO,GAAG,CAAC;AAC5B,MAAI,OAAQ,IAAI,IAAK;AAGrB,MAAI,UAAU,IAAI,OAAO,OAAO,OAAO,IAAI;AAC3C,MAAI,QAAQ,MAAM,QAAQ,OAAO;AACjC,MAAI,QAAQ,MAAM,QAAQ,OAAO;AAGjC,MAAI,KAAK,IAAI,QAAQ,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;AAChG,SAAO;AACX;AAeO,SAAS,qBAAqB,QAAQ,WAAW,IACxD;AACI,QAAM,IAAI,OAAO;AACjB,QAAM,IAAI,OAAO;AAEjB,MAAI,QAAQ,IAAI;AAChB,MAAI,SAAS,IAAI,OAAO,GAAG,CAAC;AAC5B,MAAI,OAAQ,IAAI,IAAK;AAGrB,MAAI,UAAU,IAAI,OAAO,OAAO,OAAO,IAAI;AAC3C,MAAI,QAAQ,MAAM,QAAQ,OAAO;AACjC,MAAI,QAAQ,MAAM,QAAQ,OAAO;AAGjC,MAAI,KAAK,GAAG,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM;AAC5C,MAAI,KAAK,GAAG,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM;AAG5C,MAAI,KAAK,IAAI,OAAO,IAAI,GAAG,IAAI,CAAC;AAChC,SAAO;AACX;;;AChrBA,IAAM,cAAN,MACA;AAAA,EACI,cACA;AACI,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,YAAN,MACP;AAAA,EACI,OAAO,aACH;AAAA,IACI,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,SAAS;AAAA,EACb;AAAA,EAEJ,OAAO,kBACH;AAAA,IACI,WAAW;AAAA,MACP,EAAE,MAAM,OAAO,aAAa,IAAI,UAAU,CAAE,GAAG,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,IAAK,GAAG,QAAQ,MAAM,EAAE;AAAA,MAC/H,EAAE,MAAM,SAAS,aAAa,GAAG,UAAU,CAAE,GAAG,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,IAAI;AAAA,MACpJ,EAAE,MAAM,QAAQ,aAAa,GAAG,UAAU,CAAE,GAAG,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,OAAQ,GAAG,SAAS,CAAE,GAAG,MAAO,GAAG,QAAQ,KAAK,GAAG,eAAe,MAAM,eAAe,IAAI;AAAA,MAC1K,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,EAAE;AAAA,MACzI,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,MAAM,QAAQ;AAAA,MAC3K,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,EAAE;AAAA,MAC1I,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,MAAM,QAAQ;AAAA,MAC5K,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,MAAM,GAAG,eAAe,IAAI;AAAA,MAC9J,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,MACjL,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,MAAM,GAAG,eAAe,IAAI;AAAA,MAC/J,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,GAAG,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,IACtL;AAAA,IACA,YAAY;AAAA,MACR,EAAE,UAAU,SAAS,OAAO,CAAE,GAAG,CAAI,GAAG,QAAQ,CAAE,QAAQ,KAAK,IAAI,CAAE,EAAE;AAAA,MACvE,EAAE,UAAU,QAAQ,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACjF,EAAE,UAAU,gBAAgB,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,QAAQ,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC1F,EAAE,UAAU,gBAAgB,OAAO,CAAE,GAAG,KAAM,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,QAAQ,KAAK,EAAG,EAAE;AAAA,MAC7F,EAAE,UAAU,iBAAiB,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,QAAQ,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC3F,EAAE,UAAU,iBAAiB,OAAO,CAAE,GAAG,KAAM,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,QAAQ,KAAK,EAAG,EAAE;AAAA,MAC9F,EAAE,UAAU,gBAAgB,OAAO,CAAE,GAAG,IAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC1F,EAAE,UAAU,gBAAgB,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACzF,EAAE,UAAU,iBAAiB,OAAO,CAAE,GAAG,IAAK,GAAG,QAAQ,KAAK;AAAA,MAC9D,EAAE,UAAU,iBAAiB,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,IAC9F;AAAA,EACJ;AAAA,EAEJ,OAAO,mBACH;AAAA,IACI,WAAW;AAAA,MACP,EAAE,MAAM,OAAO,aAAa,IAAI,UAAU,CAAE,GAAG,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,OAAO,CAAE,GAAG,SAAS,CAAE,MAAM,CAAE,GAAG,QAAQ,MAAM,EAAE;AAAA,MAC/H,EAAE,MAAM,SAAS,aAAa,GAAG,UAAU,CAAE,GAAG,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,IAAI;AAAA,MACpJ,EAAE,MAAM,QAAQ,aAAa,GAAG,UAAU,CAAE,GAAG,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,OAAQ,GAAG,SAAS,CAAE,GAAG,MAAO,GAAG,QAAQ,KAAK,GAAG,eAAe,MAAM,eAAe,IAAI;AAAA,MAC1K,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,MAAM,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,EAAE;AAAA,MAC5I,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,MAAM,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,MAAM,OAAO;AAAA,MAC7K,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,KAAK,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,EAAE;AAAA,MAC5I,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,KAAK,KAAM,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,MAAM,QAAQ;AAAA,MAC9K,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,OAAO,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,MAAM,KAAM,GAAG,QAAQ,MAAM,GAAG,eAAe,IAAI;AAAA,MACpK,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,OAAO,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,MACpL,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,MAAM,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,OAAO,KAAM,GAAG,QAAQ,MAAM,GAAG,eAAe,IAAI;AAAA,MACrK,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,MAAM,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,MAAO,GAAG,SAAS,CAAE,GAAG,KAAM,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,IACxL;AAAA,IACA,YAAY;AAAA,MACR,EAAE,UAAU,SAAS,OAAO,CAAE,GAAG,CAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAClF,EAAE,UAAU,QAAQ,OAAO,CAAE,GAAG,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACjF,EAAE,UAAU,gBAAgB,OAAO,CAAE,MAAM,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC5F,EAAE,UAAU,gBAAgB,OAAO,CAAE,MAAM,KAAM,GAAG,QAAQ,CAAE,GAAG,MAAM,KAAK,EAAG,EAAE;AAAA,MACjF,EAAE,UAAU,iBAAiB,OAAO,CAAE,KAAK,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC5F,EAAE,UAAU,iBAAiB,OAAO,CAAE,KAAK,KAAM,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,CAAE,EAAE;AAAA,MAClF,EAAE,UAAU,gBAAgB,OAAO,CAAE,OAAO,IAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC9F,EAAE,UAAU,gBAAgB,OAAO,CAAE,OAAO,GAAK,GAAG,QAAQ,CAAE,GAAG,OAAO,KAAK,EAAG,EAAE;AAAA,MAClF,EAAE,UAAU,iBAAiB,OAAO,CAAE,MAAM,IAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC9F,EAAE,UAAU,iBAAiB,OAAO,CAAE,MAAM,GAAK,GAAG,QAAQ,CAAE,GAAG,OAAO,KAAK,EAAG,EAAE;AAAA,IACtF;AAAA,EACJ;AAAA,EAEJ,OAAO,gBACH;AAAA,IACI,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,EACb;AAAA,EAEJ,OAAO,mBAAmB;AAAA,IACtB,WAAW;AAAA,MACP,EAAE,MAAM,SAAS,aAAa,IAAI,UAAU,CAAE,GAAG,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,KAAK,CAAE,GAAG,SAAS,CAAE,MAAM,CAAE,GAAG,QAAQ,IAAI,GAAG,eAAe,IAAI;AAAA,MAChJ,EAAE,MAAM,QAAQ,aAAa,GAAG,UAAU,CAAE,MAAM,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,KAAK,CAAE,GAAG,SAAS,CAAE,MAAM,CAAE,GAAG,QAAQ,KAAK,GAAG,eAAe,MAAM,eAAe,IAAI;AAAA,MACvK,EAAE,MAAM,aAAa,aAAa,GAAG,UAAU,CAAE,OAAO,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,MACrI,EAAE,MAAM,YAAY,aAAa,GAAG,UAAU,CAAE,OAAO,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,MACnI,EAAE,MAAM,YAAY,aAAa,GAAG,UAAU,CAAE,OAAO,IAAK,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,MAC5K,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,MAAM,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,IAAI,EAAE;AAAA,MACtI,EAAE,MAAM,iBAAiB,aAAa,GAAG,UAAU,CAAE,MAAM,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,GAAG,eAAe,IAAI;AAAA,MAC3J,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,KAAK,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,MACrI,EAAE,MAAM,gBAAgB,aAAa,GAAG,UAAU,CAAE,KAAK,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,IAAI,GAAG,eAAe,IAAI;AAAA,MACxJ,EAAE,MAAM,QAAQ,aAAa,GAAG,UAAU,CAAE,KAAK,GAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,IAAK,GAAG,SAAS,CAAE,GAAG,GAAI,GAAG,QAAQ,KAAK,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,MACrK,EAAE,MAAM,OAAO,aAAa,GAAG,UAAU,CAAE,MAAM,CAAI,GAAG,SAAS,EAAE,SAAS,CAAE,GAAG,KAAM,GAAG,SAAS,CAAE,GAAG,IAAK,GAAG,QAAQ,IAAI,GAAG,eAAe,KAAK,eAAe,IAAI;AAAA,IAC1K;AAAA,IACA,YAAY;AAAA,MACR,EAAE,UAAU,QAAQ,OAAO,CAAE,IAAM,CAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACpF,EAAE,UAAU,aAAa,OAAO,CAAE,OAAO,CAAE,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACxF,EAAE,UAAU,YAAY,OAAO,CAAE,OAAO,IAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC1F,EAAE,UAAU,YAAY,OAAO,CAAE,OAAO,IAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC1F,EAAE,UAAU,iBAAiB,OAAO,CAAE,MAAM,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC7F,EAAE,UAAU,iBAAiB,OAAO,CAAE,MAAM,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC7F,EAAE,UAAU,gBAAgB,OAAO,CAAE,KAAK,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC3F,EAAE,UAAU,gBAAgB,OAAO,CAAE,KAAK,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MAC3F,EAAE,UAAU,QAAQ,OAAO,CAAE,KAAK,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,MACnF,EAAE,UAAU,OAAO,OAAO,CAAE,MAAM,GAAI,GAAG,QAAQ,CAAE,OAAO,KAAK,IAAI,MAAM,KAAK,EAAG,EAAE;AAAA,IACvF;AAAA,EACJ;AACJ;AAEO,IAAM,UAAN,MACP;AAAA,EACI,YAAY,UAAU,GAAG,GAAG,SAAS,YAAY,OAAO,OAAO,GAC/D;AACI,SAAK,WAAW;AAChB,SAAK,WAAW,IAAI,OAAO,GAAG,CAAC;AAC/B,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,YAAY,KAAK,iBAAiB,KAAK;AAC5C,SAAK,UAAU,CAAC;AAEhB,SAAK,OAAO;AAAA,EAChB;AAAA,EAEA,WAAW,UACX;AACI,UAAM,EAAE,OAAO,IAAI,cAAc;AAAA,MAC7B,SAAS,KAAK;AAAA,MACd,UAAU,MAAM,IAAI,OAAO,SAAS,SAAS,CAAC,IAAI,KAAK,SAAS,SAAS,SAAS,CAAC,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ;AAAA,MACnH,MAAM,WAAW;AAAA,MACjB,SAAS,IAAI,OAAO,SAAS,QAAQ,QAAQ,CAAC,IAAI,KAAK,SAAS,SAAS,QAAQ,QAAQ,CAAC,IAAI,KAAK,OAAO;AAAA,MAC1G,SAAS,IAAI,OAAO,SAAS,QAAQ,QAAQ,CAAC,IAAI,KAAK,SAAS,SAAS,QAAQ,QAAQ,CAAC,IAAI,KAAK,OAAO;AAAA,MAC1G,QAAQ,SAAS,QAAQ,SAAS,KAAK;AAAA,MACvC,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY,CAAC,KAAK;AAAA,MAClB,OAAO,KAAK;AAAA,IAChB,CAAC;AAED,UAAM,OAAO,IAAI,YAAY;AAC7B,SAAK,OAAO,SAAS;AACrB,SAAK,cAAc,SAAS;AAC5B,SAAK,gBAAgB,SAAS,iBAAiB;AAC/C,SAAK,SAAS;AAEd,QAAI,SAAS,MACb;AACI,YAAM,eAAe,kBAAkB;AACvC,mBAAa,UAAU;AACvB,mBAAa,WAAW;AACxB,mBAAa,OAAO,aAAa,CAAC,KAAK;AACvC,mBAAa,OAAO,WAAW;AAC/B,mBAAa,cAAc,KAAK;AAEhC,YAAM,UAAU,SAAS,QAAQ,SAAS,KAAK;AAC/C,YAAM,cAAc,IAAI,UAAU;AAClC,kBAAY,UAAU,IAAI,OAAO,UAAU,QAAQ,KAAK,SAAS,SAAS,KAAK,OAAO;AACtF,kBAAY,UAAU,IAAI,OAAO,UAAU,OAAO,KAAK,SAAS,SAAS,KAAK,OAAO;AACrF,kBAAY,SAAS,OAAO,KAAK;AACjC,2BAAqB,QAAQ,cAAc,WAAW;AAAA,IAC1D;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,YAAY,WACZ;AACI,UAAM,OAAO,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU,QAAQ;AACjE,UAAM,aAAa,KAAK,QAAQ,KAAK,WAAW;AAEhD,UAAM,QAAQ,MAAM,IAAI,OAAO,UAAU,MAAM,CAAC,IAAI,KAAK,SAAS,UAAU,MAAM,CAAC,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ;AACnH,UAAM,WAAW,IAAI,mBAAmB;AACxC,aAAS,UAAU,WAAW;AAC9B,aAAS,UAAU,KAAK;AACxB,aAAS,eAAe,qBAAqB,SAAS,SAAS,KAAK;AACpE,aAAS,eAAe,qBAAqB,SAAS,SAAS,KAAK;AAEpE,QAAI,UAAU,QACd;AACI,eAAS,cAAc;AACvB,eAAS,aAAa,UAAU,OAAO,CAAC;AACxC,eAAS,aAAa,UAAU,OAAO,CAAC;AAAA,IAC5C;AAEA,aAAS,cAAc;AACvB,aAAS,iBAAiB,KAAK,gBAAgB,KAAK;AACpD,aAAS,eAAe,KAAK,QAAQ;AACrC,aAAS,QAAQ,KAAK;AACtB,aAAS,eAAe,KAAK;AAC7B,aAAS,WAAW,KAAK;AAEzB,WAAO,sBAAsB,KAAK,SAAS,QAAQ;AAAA,EACvD;AAAA,EAEA,SACA;AACI,SAAK,UAAU,KAAK,SAAS,UAAU,IAAI,cAAY,KAAK,WAAW,QAAQ,CAAC;AAEhF,SAAK,SAAS,WAAW,QAAQ,eACjC;AACI,YAAM,OAAO,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU,QAAQ;AACjE,WAAK,UAAU,KAAK,YAAY,SAAS;AAAA,IAC7C,CAAC;AAED,SAAK,QAAQ,QAAQ,UAAQ,mBAAmB,KAAK,QAAQ,IAAI,CAAC;AAElE,WAAO;AAAA,EACX;AAAA,EAEA,UACA;AACI,aAAU,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,EAAE,GAC5C;AACI,UAAK,KAAK,QAAQ,CAAC,EAAE,SACrB;AACI,YAAK,KAAK,QAAQ,CAAC,EAAE,QAAQ,SAAS,KAAK,eAC3C;AACI,yBAAgB,KAAK,QAAQ,CAAC,EAAE,OAAQ;AACxC,eAAK,QAAQ,CAAC,EAAE,UAAU,IAAI,UAAU;AAAA,QAC5C;AAAA,MACJ;AAAA,IACJ;AAEA,aAAU,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,EAAE,GAC5C;AACI,UAAK,KAAK,QAAQ,CAAC,EAAE,OAAO,SAAS,KAAK,eAC1C;AACI,sBAAe,KAAK,QAAQ,CAAC,EAAE,MAAO;AACtC,aAAK,QAAQ,CAAC,EAAE,SAAS;AAAA,MAC7B;AAAA,IACJ;AACA,SAAK,UAAU;AAAA,EACnB;AACJ;;;AC7QA,SAAS,OAAO,OAAO,WACvB;AACI,SAAO,SAAS,KAAK,OAAO,IAAI,OAAO;AAC3C;AAEO,IAAM,aAAN,MACP;AAAA,EACI,YAAY,IAAI,aAChB;AACI,SAAK,KAAK;AACV,SAAK,UAAU;AAAA,EACnB;AACJ;AAEA,SAAS,UAAU,eAAe,YAAY,QAAQ,SAAS,OAAO,SACtE;AACI,QAAM,cAAc,iBAAiB;AACrC,cAAY,OAAO,WAAW;AAC9B,cAAY,gBAAgB;AAC5B,cAAY,WAAW,cAAc,MAAM;AAE3C,QAAM,eAAe,kBAAkB;AACvC,eAAa,UAAU;AACvB,eAAa,WAAW;AACxB,eAAa,cAAc;AAC3B,eAAa,cAAc;AAE3B,QAAM,SAAS,aAAa,SAAS,WAAW;AAChD,QAAM,OAAO,IAAI,SAAS;AAC1B,OAAK,SAAS,IAAI,OAAO,GAAG,CAAC;AAC7B,OAAK,SAAS;AACd,sBAAoB,QAAQ,cAAc,IAAI;AAE9C,QAAM,QAAQ,IAAI,OAAO,OAAO,WAAW,GAAG,GAAG,GAAG,OAAO,WAAW,GAAG,IAAI,CAAC;AAC9E,4BAA0B,QAAQ,OAAO,IAAI;AAE7C,SAAO;AACX;AAEO,IAAM,MAAN,MACP;AAAA,EACI,YAAY,UAAU,OAAO,WAAW,MAAM,QAAQ,SAAS,OAAO,SACtE;AACI,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,QAAQ;AAEb,SAAK,cAAc,CAAC;AACpB,SAAK,eAAe,KAAK;AACzB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,OAAO,IACP;AACI,QAAI,MAAM,EAAE,GAAG;AAAE;AAAA,IAAQ;AACzB,SAAK,aAAa;AAGlB,SAAK,gBAAgB;AAErB,QAAI,KAAK,gBAAgB,GACzB;AACI,WAAK,eAAe,KAAK,IAAI,KAAK,eAAe,KAAK,WAAW,IAAE,GAAG;AACtE,YAAM,SAAS,UAAU,KAAK,UAAU,KAAK,OAAO,KAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,KAAK,OAAO;AACvG,YAAM,KAAK,IAAI,WAAY,QAAQ,KAAK,SAAU;AAClD,WAAK,YAAY,KAAK,EAAE;AACxB,yBAAmB,QAAQ,EAAE;AAAA,IACjC;AAGA,aAAS,IAAI,KAAK,YAAY,SAAS,GAAG,KAAK,GAAG,EAAE,GACpD;AACI,YAAM,KAAK,KAAK,YAAY,CAAC;AAE7B,UAAI,KAAK,YAAY,GAAG,WAAW,KAAK,MACxC;AACI,aAAK,YAAY,EAAE;AAAA,MACvB;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,YAAY,IACZ;AACI,UAAM,IAAI,KAAK,YAAY,QAAQ,EAAE;AAErC,QAAI,KAAK,IACT;AACI,oBAAc,GAAG,EAAE;AACnB,WAAK,YAAY,OAAO,GAAG,CAAC;AAE5B,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,UAAN,MACP;AAAA,EACI,YAAY,UAAU,QAAQ,OAAO,OAAO,OAAO,GAAK,SACxD;AAEI,UAAM,cAAc,iBAAiB;AACrC,gBAAY,OAAO,WAAW;AAC9B,gBAAY,WAAW;AAEvB,UAAM,SAAS,aAAa,SAAS,WAAW;AAChD,UAAM,OAAO,IAAI,SAAS;AAC1B,SAAK,SAAS,IAAI,OAAO,GAAG,CAAC;AAC7B,SAAK,SAAS,IAAM;AACpB,UAAM,eAAe,kBAAkB;AACvC,iBAAa,UAAU;AACvB,iBAAa,WAAW;AACxB,iBAAa,OAAO,WAAW;AAC/B,iBAAa,cAAc;AAC3B,wBAAoB,QAAQ,cAAc,IAAI;AAG9C,UAAM,YAAY,iBAAiB;AACnC,cAAU,OAAO,WAAW;AAC5B,cAAU,WAAW;AACrB,cAAU,gBAAgB;AAC1B,UAAM,QAAQ,aAAa,SAAS,SAAS;AAC7C,UAAM,aAAa,UAAU,KAAK,MAAM,MAAM,IAAI;AAClD,UAAM,cAAc,kBAAkB;AACtC,gBAAY,UAAU;AACtB,gBAAY,WAAW;AACvB,gBAAY,cAAc;AAC1B,yBAAqB,OAAO,aAAa,UAAU;AAEnD,UAAM,WAAW,0BAA0B;AAC3C,aAAS,UAAU;AACnB,aAAS,UAAU;AACnB,aAAS,eAAe,IAAI,OAAO,GAAG,CAAC;AACvC,aAAS,eAAe,IAAI,OAAO,GAAG,CAAC;AACvC,aAAS,cAAc;AACvB,aAAS,aAAa;AACtB,aAAS,iBAAiB;AAC1B,0BAAsB,SAAS,QAAQ;AAAA,EAC3C;AACJ;;;AC2TO,IAAM,SAAS;AACf,IAAM,YAAY;AAClB,IAAM,UAAU;", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D-Render.js b/dist/PhaserBox2D-Render.js index ded607d..c3718fe 100644 --- a/dist/PhaserBox2D-Render.js +++ b/dist/PhaserBox2D-Render.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Wednesday 1 January 2025 at 15:57 + * Tuesday, 14 January 2025 at 17:14 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -456,7 +456,7 @@ function b2GetLengthUnitsPerMeter() { function b2SetAssertFcn(assertFcn) { } function b2GetVersion() { - return new b2Version(3, 0, 0); + return new b2Version(3, 1, 0); } // src/include/core_h.js @@ -1477,7 +1477,6 @@ var b2DebugDraw = class { this.DrawCircle = null; this.DrawImageCircle = null; this.DrawSolidCircle = null; - this.DrawCapsule = null; this.DrawImageCapsule = null; this.DrawSolidCapsule = null; this.DrawSegment = null; @@ -2575,10 +2574,10 @@ function b2MakeRoundedBox(hx, hy, radius) { shape.radius = radius; return shape; } -function b2MakeOffsetBox(hx, hy, center, angle = 0) { +function b2MakeOffsetBox(hx, hy, center, rotation) { const xf2 = new b2Transform(); xf2.p = center; - xf2.q = b2MakeRot(angle); + xf2.q = rotation; const shape = new b2Polygon(); shape.count = 4; shape.vertices[0] = b2TransformPoint(xf2, new b2Vec2(-hx, -hy)); @@ -3014,9 +3013,6 @@ function b2GetShape(world, shapeId) { const shape = world.shapeArray[id]; return shape; } -function b2GetOwnerTransform(world, shape) { - return b2GetBodyTransform(world, shape.bodyId); -} function b2GetChainShape(world, chainId) { const id = chainId.index1 - 1; const chain = world.chainArray[id]; @@ -3088,7 +3084,7 @@ function b2CreateShapeInternal(world, body, transform, def, geometry, shapeType) shape.revision += 1; if (body.setIndex != b2SetType.b2_disabledSet) { const proxyType = body.type; - b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation); + b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor); } if (body.headShapeId != B2_NULL_INDEX) { const headShape = world.shapeArray[body.headShapeId]; @@ -3530,7 +3526,7 @@ function b2Shape_IsSensor(shapeId) { function b2Shape_TestPoint(shapeId, point) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); + const transform = b2GetBodyTransform(world, shape.bodyId); const localPoint = b2InvTransformPoint(transform, point); switch (shape.type) { case b2ShapeType.b2_capsuleShape: @@ -3543,30 +3539,30 @@ function b2Shape_TestPoint(shapeId, point) { return false; } } -function b2Shape_RayCast(shapeId, origin, translation) { +function b2Shape_RayCast(shapeId, input) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); - const input = new b2RayCastInput(); - input.maxFraction = 1; - input.origin = b2InvTransformPoint(transform, origin); - input.translation = b2InvRotateVector(transform.q, translation); + const transform = b2GetBodyTransform(world, shape.bodyId); + const localInput = new b2RayCastInput(); + localInput.origin = b2InvTransformPoint(transform, input.origin); + localInput.translation = b2InvRotateVector(transform.q, input.translation); + localInput.maxFraction = input.maxFraction; let output = new b2CastOutput(rayNormal3, rayPoint3); switch (shape.type) { case b2ShapeType.b2_capsuleShape: - output = b2RayCastCapsule(input, shape.capsule); + output = b2RayCastCapsule(localInput, shape.capsule); break; case b2ShapeType.b2_circleShape: - output = b2RayCastCircle(input, shape.circle); + output = b2RayCastCircle(localInput, shape.circle); break; case b2ShapeType.b2_segmentShape: - output = b2RayCastSegment(input, shape.segment, false); + output = b2RayCastSegment(localInput, shape.segment, false); break; case b2ShapeType.b2_polygonShape: - output = b2RayCastPolygon(input, shape.polygon); + output = b2RayCastPolygon(localInput, shape.polygon); break; case b2ShapeType.b2_chainSegmentShape: - output = b2RayCastSegment(input, shape.chainSegment.segment, true); + output = b2RayCastSegment(localInput, shape.chainSegment.segment, true); break; default: return output; @@ -6884,12 +6880,12 @@ function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); base.distanceJoint.dampingRatio = dampingRatio; } -function b2DistanceJoint_GetHertz(jointId) { +function b2DistanceJoint_GetSpringHertz(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.hertz; } -function b2DistanceJoint_GetDampingRatio(jointId) { +function b2DistanceJoint_GetSpringDampingRatio(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.dampingRatio; @@ -8789,7 +8785,8 @@ function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideCon } } if (joint.setIndex > b2SetType.b2_disabledSet) { - b2LinkJoint(world, joint); + const mergeIslands = true; + b2LinkJoint(world, joint, mergeIslands); } b2ValidateSolverSets(world); return new b2JointPair(joint, jointSim); @@ -9067,7 +9064,9 @@ function b2DestroyJointInternal(world, joint, wakeBodies) { bodyB.headJointKey = edgeB.nextKey; } bodyB.jointCount -= 1; - b2UnlinkJoint(world, joint); + if (joint.islandId !== B2_NULL_INDEX) { + b2UnlinkJoint(world, joint); + } const setIndex = joint.setIndex; const localIndex = joint.localIndex; if (setIndex === b2SetType.b2_awakeSet) { @@ -9969,7 +9968,7 @@ function b2AddJointToIsland(world, islandId, joint) { joint.islandId = islandId; b2ValidateIsland(world, islandId); } -function b2LinkJoint(world, joint) { +function b2LinkJoint(world, joint, mergeIslands) { const bodyA = b2GetBody(world, joint.edges[0].bodyId); const bodyB = b2GetBody(world, joint.edges[1].bodyId); if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet) { @@ -10015,6 +10014,9 @@ function b2LinkJoint(world, joint) { } else { b2AddJointToIsland(world, islandIdB, joint); } + if (mergeIslands) { + b2MergeAwakeIslands(world); + } } function b2UnlinkJoint(world, joint) { const islandId = joint.islandId; @@ -11006,11 +11008,11 @@ function b2Body_SetType(bodyId, type) { if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody) { continue; } - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, false); } + b2MergeAwakeIslands(world); } b2UpdateBodyMassData(world, body); - b2ValidateConnectivity(world); b2ValidateSolverSets(world); } function b2Body_SetUserData(bodyId, userData) { @@ -11029,7 +11031,7 @@ function b2Body_GetMass(bodyId) { const bodySim = b2GetBodySim(world, body); return bodySim.mass; } -function b2Body_GetInertiaTensor(bodyId) { +function b2Body_GetRotationalInertia(bodyId) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); const bodySim = b2GetBodySim(world, body); @@ -11158,10 +11160,10 @@ function b2Body_IsSleepEnabled(bodyId) { const body = b2GetBodyFullId(world, bodyId); return body.enableSleep; } -function b2Body_SetSleepThreshold(bodyId, sleepVelocity) { +function b2Body_SetSleepThreshold(bodyId, sleepThreshold) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); - body.sleepThreshold = sleepVelocity; + body.sleepThreshold = sleepThreshold; } function b2Body_GetSleepThreshold(bodyId) { const world = b2GetWorld(bodyId.world0); @@ -11243,6 +11245,7 @@ function b2Body_Enable(bodyId) { if (setId !== b2SetType.b2_staticSet) { b2CreateIslandForBody(world, setId, body); } + const mergeIslands = false; let jointKey = body.headJointKey; while (jointKey !== B2_NULL_INDEX) { const jointId = jointKey >> 1; @@ -11265,10 +11268,10 @@ function b2Body_Enable(bodyId) { const jointSet = world.solverSetArray[jointSetId]; b2TransferJoint(world, jointSet, disabledSet, joint); if (jointSetId !== b2SetType.b2_staticSet) { - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, mergeIslands); } } - b2ValidateConnectivity(world); + b2MergeAwakeIslands(world); b2ValidateSolverSets(world); } function b2Body_SetFixedRotation(bodyId, flag) { @@ -11709,7 +11712,8 @@ var p2 = new b2Vec2(); var q1 = new b2Vec2(); var q2 = new b2Vec2(); function b2MakeCapsule(p14, p23, radius) { - const axis = b2NormalizeChecked(b2Sub(p23, p14)); + const d = b2Sub(p23, p14); + const axis = b2Normalize(d); const normal = b2RightPerp(axis); const shape = new b2Polygon(); shape.vertices = [p14, p23]; @@ -12148,7 +12152,7 @@ function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold) { constCapsule.center1 = segmentA.point1; constCapsule.center2 = segmentA.point2; constCapsule.radius = 0; - return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB); + return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold); } function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold) { const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius); @@ -15570,7 +15574,7 @@ function CreateBoxPolygon(data) { let box; if (data.size instanceof b2Vec2) { if (data.bodyId) { - box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, 0); + box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0)); } else { box = b2MakeBox(data.size.x, data.size.y); } @@ -15976,9 +15980,6 @@ function CreateDebugDraw(canvas, ctx, scale = 20) { } const draw = new b2DebugDraw(); if (disableDrawing) { - draw.DrawCapsule = () => { - return; - }; draw.DrawCircle = () => { return; }; @@ -16813,7 +16814,6 @@ export { b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_GetGravityScale, - b2Body_GetInertiaTensor, b2Body_GetJointCount, b2Body_GetJoints, b2Body_GetLinearDamping, @@ -16825,6 +16825,7 @@ export { b2Body_GetMassData, b2Body_GetPosition, b2Body_GetRotation, + b2Body_GetRotationalInertia, b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetSleepThreshold, @@ -16934,14 +16935,14 @@ export { b2DistanceJoint_EnableMotor, b2DistanceJoint_EnableSpring, b2DistanceJoint_GetCurrentLength, - b2DistanceJoint_GetDampingRatio, - b2DistanceJoint_GetHertz, b2DistanceJoint_GetLength, b2DistanceJoint_GetMaxLength, b2DistanceJoint_GetMaxMotorForce, b2DistanceJoint_GetMinLength, b2DistanceJoint_GetMotorForce, b2DistanceJoint_GetMotorSpeed, + b2DistanceJoint_GetSpringDampingRatio, + b2DistanceJoint_GetSpringHertz, b2DistanceJoint_IsLimitEnabled, b2DistanceJoint_IsMotorEnabled, b2DistanceJoint_IsSpringEnabled, diff --git a/dist/PhaserBox2D-Render.js.map b/dist/PhaserBox2D-Render.js.map index 14ac5fd..ef759af 100644 --- a/dist/PhaserBox2D-Render.js.map +++ b/dist/PhaserBox2D-Render.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 0, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawCapsule = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MakeRot,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {number} angle - The rotation angle of the box in radians\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, angle = 0)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = b2MakeRot(angle);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\nexport function b2GetOwnerTransform(world, shape)\n{\n return b2GetBodyTransform(world, shape.bodyId);\n}\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetOwnerTransform(world, shape);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2Vec2} origin - The starting point of the ray in world coordinates\n * @param {b2Vec2} translation - The direction and length of the ray in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, origin, translation)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetOwnerTransform(world, shape);\n\n // input in local coordinates\n const input = new b2RayCastInput();\n input.maxFraction = 1.0;\n input.origin = b2InvTransformPoint(transform, origin);\n input.translation = b2InvRotateVector(transform.q, translation);\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(input, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(input, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(input, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(input, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(input, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2GetOwnerTransform,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // let rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // let rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // let ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId != B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n b2LinkJoint(world, joint);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n b2UnlinkJoint(world, joint);\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint);\n }\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Gets the inertia tensor value for a specified body.\n * @function b2Body_GetInertiaTensor\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetInertiaTensor(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepVelocity - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepVelocity;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint);\n }\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetInertiaTensor, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeChecked,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const axis = b2NormalizeChecked(b2Sub(p2, p1));\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_EnableWarmStarting,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, 0);\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCapsule = () => { return; }\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetInertiaTensor,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetHertz,\n b2DistanceJoint_GetDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": "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", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D.js b/dist/PhaserBox2D.js index 8b51350..b3315a1 100644 --- a/dist/PhaserBox2D.js +++ b/dist/PhaserBox2D.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Wednesday 1 January 2025 at 15:57 + * Tuesday, 14 January 2025 at 17:14 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -456,7 +456,7 @@ function b2GetLengthUnitsPerMeter() { function b2SetAssertFcn(assertFcn) { } function b2GetVersion() { - return new b2Version(3, 0, 0); + return new b2Version(3, 1, 0); } // src/include/core_h.js @@ -1477,7 +1477,6 @@ var b2DebugDraw = class { this.DrawCircle = null; this.DrawImageCircle = null; this.DrawSolidCircle = null; - this.DrawCapsule = null; this.DrawImageCapsule = null; this.DrawSolidCapsule = null; this.DrawSegment = null; @@ -2575,10 +2574,10 @@ function b2MakeRoundedBox(hx, hy, radius) { shape.radius = radius; return shape; } -function b2MakeOffsetBox(hx, hy, center, angle = 0) { +function b2MakeOffsetBox(hx, hy, center, rotation) { const xf2 = new b2Transform(); xf2.p = center; - xf2.q = b2MakeRot(angle); + xf2.q = rotation; const shape = new b2Polygon(); shape.count = 4; shape.vertices[0] = b2TransformPoint(xf2, new b2Vec2(-hx, -hy)); @@ -3014,9 +3013,6 @@ function b2GetShape(world, shapeId) { const shape = world.shapeArray[id]; return shape; } -function b2GetOwnerTransform(world, shape) { - return b2GetBodyTransform(world, shape.bodyId); -} function b2GetChainShape(world, chainId) { const id = chainId.index1 - 1; const chain = world.chainArray[id]; @@ -3088,7 +3084,7 @@ function b2CreateShapeInternal(world, body, transform, def, geometry, shapeType) shape.revision += 1; if (body.setIndex != b2SetType.b2_disabledSet) { const proxyType = body.type; - b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation); + b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor); } if (body.headShapeId != B2_NULL_INDEX) { const headShape = world.shapeArray[body.headShapeId]; @@ -3530,7 +3526,7 @@ function b2Shape_IsSensor(shapeId) { function b2Shape_TestPoint(shapeId, point) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); + const transform = b2GetBodyTransform(world, shape.bodyId); const localPoint = b2InvTransformPoint(transform, point); switch (shape.type) { case b2ShapeType.b2_capsuleShape: @@ -3543,30 +3539,30 @@ function b2Shape_TestPoint(shapeId, point) { return false; } } -function b2Shape_RayCast(shapeId, origin, translation) { +function b2Shape_RayCast(shapeId, input) { const world = b2GetWorld(shapeId.world0); const shape = b2GetShape(world, shapeId); - const transform = b2GetOwnerTransform(world, shape); - const input = new b2RayCastInput(); - input.maxFraction = 1; - input.origin = b2InvTransformPoint(transform, origin); - input.translation = b2InvRotateVector(transform.q, translation); + const transform = b2GetBodyTransform(world, shape.bodyId); + const localInput = new b2RayCastInput(); + localInput.origin = b2InvTransformPoint(transform, input.origin); + localInput.translation = b2InvRotateVector(transform.q, input.translation); + localInput.maxFraction = input.maxFraction; let output = new b2CastOutput(rayNormal3, rayPoint3); switch (shape.type) { case b2ShapeType.b2_capsuleShape: - output = b2RayCastCapsule(input, shape.capsule); + output = b2RayCastCapsule(localInput, shape.capsule); break; case b2ShapeType.b2_circleShape: - output = b2RayCastCircle(input, shape.circle); + output = b2RayCastCircle(localInput, shape.circle); break; case b2ShapeType.b2_segmentShape: - output = b2RayCastSegment(input, shape.segment, false); + output = b2RayCastSegment(localInput, shape.segment, false); break; case b2ShapeType.b2_polygonShape: - output = b2RayCastPolygon(input, shape.polygon); + output = b2RayCastPolygon(localInput, shape.polygon); break; case b2ShapeType.b2_chainSegmentShape: - output = b2RayCastSegment(input, shape.chainSegment.segment, true); + output = b2RayCastSegment(localInput, shape.chainSegment.segment, true); break; default: return output; @@ -6884,12 +6880,12 @@ function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); base.distanceJoint.dampingRatio = dampingRatio; } -function b2DistanceJoint_GetHertz(jointId) { +function b2DistanceJoint_GetSpringHertz(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.hertz; } -function b2DistanceJoint_GetDampingRatio(jointId) { +function b2DistanceJoint_GetSpringDampingRatio(jointId) { const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint); const joint = base.distanceJoint; return joint.dampingRatio; @@ -8789,7 +8785,8 @@ function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideCon } } if (joint.setIndex > b2SetType.b2_disabledSet) { - b2LinkJoint(world, joint); + const mergeIslands = true; + b2LinkJoint(world, joint, mergeIslands); } b2ValidateSolverSets(world); return new b2JointPair(joint, jointSim); @@ -9067,7 +9064,9 @@ function b2DestroyJointInternal(world, joint, wakeBodies) { bodyB.headJointKey = edgeB.nextKey; } bodyB.jointCount -= 1; - b2UnlinkJoint(world, joint); + if (joint.islandId !== B2_NULL_INDEX) { + b2UnlinkJoint(world, joint); + } const setIndex = joint.setIndex; const localIndex = joint.localIndex; if (setIndex === b2SetType.b2_awakeSet) { @@ -9969,7 +9968,7 @@ function b2AddJointToIsland(world, islandId, joint) { joint.islandId = islandId; b2ValidateIsland(world, islandId); } -function b2LinkJoint(world, joint) { +function b2LinkJoint(world, joint, mergeIslands) { const bodyA = b2GetBody(world, joint.edges[0].bodyId); const bodyB = b2GetBody(world, joint.edges[1].bodyId); if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet) { @@ -10015,6 +10014,9 @@ function b2LinkJoint(world, joint) { } else { b2AddJointToIsland(world, islandIdB, joint); } + if (mergeIslands) { + b2MergeAwakeIslands(world); + } } function b2UnlinkJoint(world, joint) { const islandId = joint.islandId; @@ -11006,11 +11008,11 @@ function b2Body_SetType(bodyId, type) { if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody) { continue; } - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, false); } + b2MergeAwakeIslands(world); } b2UpdateBodyMassData(world, body); - b2ValidateConnectivity(world); b2ValidateSolverSets(world); } function b2Body_SetUserData(bodyId, userData) { @@ -11029,7 +11031,7 @@ function b2Body_GetMass(bodyId) { const bodySim = b2GetBodySim(world, body); return bodySim.mass; } -function b2Body_GetInertiaTensor(bodyId) { +function b2Body_GetRotationalInertia(bodyId) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); const bodySim = b2GetBodySim(world, body); @@ -11158,10 +11160,10 @@ function b2Body_IsSleepEnabled(bodyId) { const body = b2GetBodyFullId(world, bodyId); return body.enableSleep; } -function b2Body_SetSleepThreshold(bodyId, sleepVelocity) { +function b2Body_SetSleepThreshold(bodyId, sleepThreshold) { const world = b2GetWorld(bodyId.world0); const body = b2GetBodyFullId(world, bodyId); - body.sleepThreshold = sleepVelocity; + body.sleepThreshold = sleepThreshold; } function b2Body_GetSleepThreshold(bodyId) { const world = b2GetWorld(bodyId.world0); @@ -11243,6 +11245,7 @@ function b2Body_Enable(bodyId) { if (setId !== b2SetType.b2_staticSet) { b2CreateIslandForBody(world, setId, body); } + const mergeIslands = false; let jointKey = body.headJointKey; while (jointKey !== B2_NULL_INDEX) { const jointId = jointKey >> 1; @@ -11265,10 +11268,10 @@ function b2Body_Enable(bodyId) { const jointSet = world.solverSetArray[jointSetId]; b2TransferJoint(world, jointSet, disabledSet, joint); if (jointSetId !== b2SetType.b2_staticSet) { - b2LinkJoint(world, joint); + b2LinkJoint(world, joint, mergeIslands); } } - b2ValidateConnectivity(world); + b2MergeAwakeIslands(world); b2ValidateSolverSets(world); } function b2Body_SetFixedRotation(bodyId, flag) { @@ -11709,7 +11712,8 @@ var p2 = new b2Vec2(); var q1 = new b2Vec2(); var q2 = new b2Vec2(); function b2MakeCapsule(p14, p23, radius) { - const axis = b2NormalizeChecked(b2Sub(p23, p14)); + const d = b2Sub(p23, p14); + const axis = b2Normalize(d); const normal = b2RightPerp(axis); const shape = new b2Polygon(); shape.vertices = [p14, p23]; @@ -12148,7 +12152,7 @@ function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold) { constCapsule.center1 = segmentA.point1; constCapsule.center2 = segmentA.point2; constCapsule.radius = 0; - return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB); + return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold); } function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold) { const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius); @@ -15797,7 +15801,7 @@ function CreateBoxPolygon(data) { let box; if (data.size instanceof b2Vec2) { if (data.bodyId) { - box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, 0); + box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0)); } else { box = b2MakeBox(data.size.x, data.size.y); } @@ -16250,7 +16254,6 @@ export { b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_GetGravityScale, - b2Body_GetInertiaTensor, b2Body_GetJointCount, b2Body_GetJoints, b2Body_GetLinearDamping, @@ -16262,6 +16265,7 @@ export { b2Body_GetMassData, b2Body_GetPosition, b2Body_GetRotation, + b2Body_GetRotationalInertia, b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetSleepThreshold, @@ -16371,14 +16375,14 @@ export { b2DistanceJoint_EnableMotor, b2DistanceJoint_EnableSpring, b2DistanceJoint_GetCurrentLength, - b2DistanceJoint_GetDampingRatio, - b2DistanceJoint_GetHertz, b2DistanceJoint_GetLength, b2DistanceJoint_GetMaxLength, b2DistanceJoint_GetMaxMotorForce, b2DistanceJoint_GetMinLength, b2DistanceJoint_GetMotorForce, b2DistanceJoint_GetMotorSpeed, + b2DistanceJoint_GetSpringDampingRatio, + b2DistanceJoint_GetSpringHertz, b2DistanceJoint_IsLimitEnabled, b2DistanceJoint_IsMotorEnabled, b2DistanceJoint_IsSpringEnabled, diff --git a/dist/PhaserBox2D.min.js b/dist/PhaserBox2D.min.js index 2d73684..e9147c3 100644 --- a/dist/PhaserBox2D.min.js +++ b/dist/PhaserBox2D.min.js @@ -1,11 +1,11 @@ /** * @license * Phaser Box2D v1.1.0 - * Wednesday 1 January 2025 at 15:57 + * Tuesday, 14 January 2025 at 17:14 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is * Copyright 2025 Phaser Studio Inc and is released under the MIT license. */ -function Ye(t){let e=Yt(t);if(ee?t:e}function k2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function T2(t,e){return te?t:e}function R2(t){return t<0?-t:t}function L2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function le(t){return new g(-t.y,t.x)}function de(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function E2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function wi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function vi(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Ji(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function j2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function be(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function pe(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Mi(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function F2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function Ci(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function q2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function V2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function Y2(t){return Math.atan2(t.s,t.c)}function N2(t){return new g(t.c,t.s)}function W2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function O2(t,e){return t.c*e.c-t.s*e.s}function U2(t,e){return t.s*e.c+t.c*e.s}function z2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function wo(t){return t<-Co?t+2*Co:t>Co?t-2*Co:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function K2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function H2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function Pi(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function vo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function $2(t){return t&&ae(t.s)&&ae(t.c)&&Ci(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function dt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function ki(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Z2=1,x=-1;function Ta(t){Z2=t}function Ga(){return Z2}function Ra(t){}function La(){return new Ti(3,0,0)}var We=1,De=1e5*We,te=2,It=.005*We;var th=.25*Math.PI,Qt=4*It,vn=.1*We,eh=.5;function oh(){}function nh(){}function sh(){}function rh(){}function ih(){}function ah(t){}function ch(t){}function lh(){}var Jo=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function dh(t){return t.index1===0}function bh(t){return t.index1!==0}function ph(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function um(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?le(e):de(e);default:return new g(0,0)}}function ym(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function mh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=uh(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=uh(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function yh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function fh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=um(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=mo(o,Ht(y)),h=o.points[u],m=mo(i,y),f=i.points[m];let v=J(h,f);y=dt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:yh(p);break;case 3:fh(p);break;default:}if(p.count===3)return e;y=ym(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;mh(B,A,p);let w=dt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function Im(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new lo,Object.assign(i.sweepA,o),i.sweepB=new lo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=dt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=dt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=dt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Sm(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=mo(t.proxyA,s),c=mo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=mo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=mo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function hh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new ue;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=hh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=dt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=pe(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=dt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new co;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new co;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new co;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new co;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new co;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function za(t,e){return he(t,e.bodyId)}function Sh(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(pe(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function yo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function Ka(t,e,o){return pe(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function _h(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&fo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ha(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);_h(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function $a(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&fo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function fc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function xc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function Ic(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Sc(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function _c(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function gc(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function Bc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Ac(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Cc(t){let e=O(t.world0);return Bt(e,t).type}function wc(t){let e=O(t.world0);return Bt(e,t).circle}function vc(t){let e=O(t.world0);return Bt(e,t).segment}function Jc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Mc(t){let e=O(t.world0);return Bt(e,t).capsule}function Dc(t){let e=O(t.world0);return Bt(e,t).polygon}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Rc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Lc(t,e){let o=ft(t.world0);if(o===null)return;let n=Sh(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Xc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function qc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new ue;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new uo,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,lt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=lt>0?1/lt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,lt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*lt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(lt*ut-Et*Ge)}for(let ot=0;otlt?lt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Uc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var Jm=1024;function Ah(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&rl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=dt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Dm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(Jm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:Bh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:Bh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Dm(t,o),o}function wh(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=al(o.bodyCount),i.contacts=cl(o.contactCount),i.joints=ll(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(xo(C.bodySet,y.edges[0].bodyId),xo(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(xo(_.bodySet,y.edges[0].bodyId),xo(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function il(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function km(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,vo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Gm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Pm(s,r,e):n===yn.b2_stageIntegratePositions&&km(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Lm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new pl;N.context=e,N.workerIndex=0,Rm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&jm(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&Fm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(gh(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function _l(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function Bl(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function Al(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Cl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function wl(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=he(o,e.bodyIdA),s=he(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function Jl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function Ml(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Dl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Pl(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Tl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Rl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Ll(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function El(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function Fl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function Xl(t,e){let o=e.distanceJoint,n=he(t,e.bodyIdA),s=he(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=dt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function ql(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=dt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Vl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=dt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function Yl(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=dt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Nl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=dt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function $l(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function Zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function td(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function ed(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function od(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function sd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function rd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function id(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function ad(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function cd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ld(t,e){let o=e.bodyIdA,n=he(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=le(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function dd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function bd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function pd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=le(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function ud(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=le(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function hd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=le(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function md(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function Id(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function Sd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function _d(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=he(e,o.bodyIdA),s=he(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=wo(r),r}function gd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function Ad(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Cd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function wd(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function vd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function Md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Dd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Pd(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function kd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Td(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function Gd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Rd(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=wo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Ed(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function jd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=wo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Fd(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function Xd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Od(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function zd(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Kd(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function Hd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function Zd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function tb(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function eb(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function ob(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function nb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function sb(t,e){let o=e.wheelJoint,n=o.axisA,s=le(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function rb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function ib(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=le(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function ab(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=le(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function cb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=le(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function lb(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=le(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function bb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-Co,Co)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function xb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function Ib(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function Sb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function _b(t,e){return t.inv_h*e.motorJoint.angularImpulse}function gb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=wo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Bb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function Ab(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=wo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),be(a.linearImpulse)>w*w&&(a.linearImpulse=dt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Cb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Pb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function kb(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Tb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function Gb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Rb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Lb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Eb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,dt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Nb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Wb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Ob(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Ub(t,e){return t.inv_h*e.weldJoint.angularImpulse}function zb(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Kb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function Hb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Qb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function Zb(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function tp(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function ep(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new ho;return t.drawSize=.25,t}function op(){return new tn}function np(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var $b=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function zn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new Un,new Un],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(il(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p),Lt(t),new $b(p,h)}function Kn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&fo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=zn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=dt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=zn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=dt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Kn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function sp(t){let e=O(t.world0);return Je(e,t).type}function rp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function ip(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function ap(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function cp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function lp(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){mp(t,i,e);return}let a=null;if(i!==x){a=_o(t,i);let d=a.parentIsland;for(;d!==x;){let p=_o(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=_o(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=_o(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?mp(t,i,e):mp(t,c,e)}function ri(t,e){let o=e.islandId,n=_o(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,go(t,o)}function yp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,go(t,e)}function Ys(t,e){let o=_t(t,e.edges[0].bodyId),n=_t(t,e.edges[1].bodyId);o.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet?qe(t,n.setIndex):n.setIndex===M.b2_awakeSet&&o.setIndex>=M.b2_firstSleepingSet&&qe(t,o.setIndex);let s=o.islandId,r=n.islandId;if(s===r){yp(t,s,e);return}let i=null;if(s!==x)for(i=_o(t,s);i.parentIsland!==x;){let a=_o(t,i.parentIsland);a.parentIsland!==x&&(i.parentIsland=a.parentIsland),s=i.parentIsland,i=a}let c=null;if(r!==x)for(c=_o(t,r);c.parentIsland!==x;){let a=_o(t,c.parentIsland);a.parentIsland!==x&&(c.parentIsland=a.parentIsland),r=c.parentIsland,c=a}i!==c&&i!==null&&c!==null&&(c.parentIsland=s),i!==null?yp(t,s,e):yp(t,r,e)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,go(t,o)}function Vm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,go(t,o)}function fl(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(Vm(t,c),si(t,i))}Hn(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;go(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}go(t,f)}}function go(t,e){if(!po)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function he(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function xp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function Ip(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&go(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function Sp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,fo(t,i,o)}Lt(t)}function Bo(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&xp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}Sp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}Ip(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function _p(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function gp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function Bp(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=he(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=tc(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function Ap(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ii(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function wp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function vp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,vo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function Jp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function Mp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Dp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;be(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Pp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function Gp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Rp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Lp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Ep(t){let e=O(t.world0);return Z(e,t).type}function jp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}Sp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),xp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?So(o,c,i,u):u.setIndex===M.b2_awakeSet&&(So(o,i,c,u),So(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),Ip(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?So(o,i,c,u):(So(o,i,c,u),So(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l))}}cn(o,n),Hn(o),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Fp(t){let e=O(t.world0);return Z(e,t).userData}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Vp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function Yp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Np(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Wp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Op(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function $p(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function tu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function eu(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function ou(t){let e=O(t.world0);return Z(e,t).enableSleep}function nu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function su(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function ru(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function iu(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;Sp(e,o,!0),Ip(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];So(e,i,p,d)}Hn(e),Lt(e)}function au(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let p=e.shapeArray[l];l=p.nextShapeId,Vn(p,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&xp(e,s,o);let d=o.headJointKey;for(;d!==x;){let p=d>>1,b=d&1,u=e.jointArray[p];d=u.edges[b].nextKey;let h=e.bodyArray[u.edges[0].bodyId],m=e.bodyArray[u.edges[1].bodyId];if(h.setIndex===M.b2_disabledSet||m.setIndex===M.b2_disabledSet)continue;let f;h.setIndex===M.b2_staticSet&&m.setIndex===M.b2_staticSet?f=M.b2_staticSet:h.setIndex===M.b2_staticSet?f=m.setIndex:f=h.setIndex;let y=e.solverSetArray[f];So(e,y,n,u),f!==M.b2_staticSet&&Ys(e,u)}Hn(e),Lt(e)}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function lu(t){let e=O(t.world0);return Z(e,t).fixedRotation}function du(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function bu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function pu(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function uu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function hu(t){let e=O(t.world0);return Z(e,t).jointCount}function mu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Ao=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function al(t){let e=new Es(t);return t>0?(e.data=bo(t,()=>new Hs),e):(e.data=null,e)}function cl(t){let e=new ln(t);return t>0?(e.data=bo(t,()=>new Qn),e):(e.data=null,e)}function ll(t){let e=new dn(t);return t>0?(e.data=bo(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=bo(Ao,()=>new Hs),t.capacity=Ao,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=bo(Ao,()=>new Pt),t.capacity=Ao,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=bo(Ao,()=>new Qn),t.capacity=Ao,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=bo(Ao,()=>new Ws),t.capacity=Ao,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=bo(Ao,()=>new Os),t.capacity=Ao,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ai(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),yu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function gu(t,e,o){let n=ki(J(e,t)),s=de(n),r=new ge;return r.vertices=[t,e],r.centroid=$t(t,e,.5),r.normals=[s,Ht(s)],r.count=2,r.radius=o,r}function ci(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function li(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;wi(e.p,1,K(e.q,r),yu.p),yu.q=e.q,Uo(yu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=pe(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let lt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(lt,Et),Jt=Math.max(-lt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let lt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(lt,Et),Jt=Math.max(-lt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let lt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);lt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);lt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,lt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+lt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;wi(D,.5*(R-X-P),b,pt),wi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function Th(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),fu=new g,xu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;fu.x=e.p.x+(e.q.c*r-e.q.s*i),fu.y=e.p.y+(e.q.s*r+e.q.c*i),xu.p=fu,xu.q=e.q,Uo(xu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else kh(kt,Ut,a,p,h,s)}else kh(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function mi(t,e,o,n,s,r){let i=gu(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function Iu(t,e,o,n,s,r,i,c,a,l){let d=le(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function Su(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var _u=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=dt(J(l,a)),p=new _u;p.edge1=d.clone();let b=.01,u=dt(J(a,t.ghost1));p.normal0=de(u),p.convex1=z(u,d)>=b;let h=dt(J(t.ghost2,l));p.normal2=de(h),p.convex2=z(d,h)>=b;let m=de(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=dt(J(et,W)),ot=Su(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=Su(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new Au)),Gh=!1;function Wm(t,e,o,n,s,r){return ci(t.circle,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Um(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function zm(t,e,o,n,s,r){return li(t.polygon,e,o.circle,n,r)}function Km(t,e,o,n,s,r){return bi(t.polygon,e,o.capsule,n,r)}function Hm(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function $m(t,e,o,n,s,r){return pi(t.segment,e,o.circle,n,r)}function Qm(t,e,o,n,s,r){return di(t.segment,e,o.capsule,n,r)}function Zm(t,e,o,n,s,r){return ui(t.segment,e,o.polygon,n,r)}function ty(t,e,o,n,s,r){return hi(t.chainSegment,e,o.circle,n,r)}function ey(t,e,o,n,s,r){return mi(t.chainSegment,e,o.capsule,n,s,r)}function oy(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Cu(){Gh===!1&&(Ve(Wm,Y.b2_circleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Um,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(zm,Y.b2_polygonShape,Y.b2_circleShape),Ve(Km,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Hm,Y.b2_polygonShape,Y.b2_polygonShape),Ve($m,Y.b2_segmentShape,Y.b2_circleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Zm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(oy,Y.b2_chainSegmentShape,Y.b2_polygonShape),Gh=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Ym(e.friction,o.friction),h.restitution=Nm(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function fo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function ny(t,e,o,n,s){let r=new ue;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var Bu=new To;function wu(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=ny(o,n,r,i,e.cache);else{e.manifold.copyTo(Bu);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Du=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Pu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function sy(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew Ju),ry(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function ry(t,e,o){let n=o.broadPhase,s=new Mu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,ly(s),s.dt>0&&hl(n,s),n.locked=!1}var An=new g,ts=new g,dy=new rt,Eu=new at(An,dy);function Eh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;K2(s,r.center,Eu),e.image?t.DrawImageCircle(Eu,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Eu,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var Xu=class{constructor(e,o){this.world=e,this.draw=o}};function by(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Eh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function py(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new Xu(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Lh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Lh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=de(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Nu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){py(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Eh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=de(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Wu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Ou(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Uu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function zu(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function t2(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function e2(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function o2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function n2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function s2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function uy(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var qu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function r2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new qu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function a2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Ii;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function d2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Za(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=dt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function S2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Vu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,my,r)}function ju(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function Hn(t){if(!po)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=ju(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=ju(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!po)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Xh(){}function qh(){}function Vh(){}var Cg=new g;var _2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Bi({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new _2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new ho;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{B2(e,o)})}function B2(t,e){let o=ii(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:g2,size:or(e.width*n/2,e.height*s/2)},i=C2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:g2,size:or(e.width*n/2,e.height*s/2)},i=A2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function tm(t){let e=t.worldDef;return e||(e=lr()),Si(),{worldId:_i(e)}}var Ja=0;function em(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Bo(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Bo(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=he(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=yo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function sm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);yo(i.bodyId,o,l)}})}function w2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);yo(i.bodyId,o,l)}})}function rm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ai(t){let e=t.jointDef;return e||(e=new ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function im(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function bm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var lA=0,dA=1,bA=2;export{Uh as AddSpriteToWorld,ph as B2_ID_EQUALS,bh as B2_IS_NON_NULL,dh as B2_IS_NULL,x as B2_NULL_INDEX,B2 as BodyToSprite,Kh as ClearWorldSprites,C2 as CreateBoxPolygon,Bi as CreateCapsule,om as CreateChain,A2 as CreateCircle,am as CreateDistanceJoint,dm as CreateMotorJoint,bm as CreateMouseJoint,nm as CreateNGonPolygon,rm as CreatePhysicsEditorShape,va as CreatePolygon,sm as CreatePolygonFromEarcut,w2 as CreatePolygonFromVertices,lm as CreatePrismaticJoint,Ai as CreateRevoluteJoint,im as CreateWeldJoint,cm as CreateWheelJoint,tm as CreateWorld,bA as DYNAMIC,Hh as GetBodyFromSprite,Nh as GetWorldScale,dA as KINEMATIC,Ca as Ragdoll,zh as RemoveSpriteFromWorld,wa as RotFromRad,lA as STATIC,Yh as SetWorldScale,Aa as Skeletons,Qh as SpriteToBox,Zh as SpriteToCircle,$h as UpdateWorldSprites,em as WorldStep,xt as b2AABB,Le as b2AABB_Center,vo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,k2 as b2AbsFloat,R2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Lp as b2Body_ApplyAngularImpulse,kp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,Gp as b2Body_ApplyLinearImpulse,Rp as b2Body_ApplyLinearImpulseToCenter,Op as b2Body_ApplyMassFromShapes,Tp as b2Body_ApplyTorque,Bp as b2Body_ComputeAABB,iu as b2Body_Disable,au as b2Body_Enable,pu as b2Body_EnableHitEvents,ru as b2Body_EnableSleep,Hp as b2Body_GetAngularDamping,Mp as b2Body_GetAngularVelocity,_p as b2Body_GetContactCapacity,gp as b2Body_GetContactData,Qp as b2Body_GetGravityScale,qp as b2Body_GetInertiaTensor,hu as b2Body_GetJointCount,mu as b2Body_GetJoints,zp as b2Body_GetLinearDamping,Jp as b2Body_GetLinearVelocity,Vp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,wp as b2Body_GetLocalVector,Xp as b2Body_GetMass,Wp as b2Body_GetMassData,Ap as b2Body_GetPosition,Us as b2Body_GetRotation,uu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,su as b2Body_GetSleepThreshold,ii as b2Body_GetTransform,Ep as b2Body_GetType,Fp as b2Body_GetUserData,Yp as b2Body_GetWorldCenterOfMass,Cp as b2Body_GetWorldPoint,vp as b2Body_GetWorldVector,Zp as b2Body_IsAwake,bu as b2Body_IsBullet,eu as b2Body_IsEnabled,lu as b2Body_IsFixedRotation,ou as b2Body_IsSleepEnabled,Ku as b2Body_IsValid,Kp as b2Body_SetAngularDamping,Pp as b2Body_SetAngularVelocity,tu as b2Body_SetAwake,du as b2Body_SetBullet,cu as b2Body_SetFixedRotation,$p as b2Body_SetGravityScale,Up as b2Body_SetLinearDamping,Dp as b2Body_SetLinearVelocity,Np as b2Body_SetMassData,nu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,jp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,$u as b2Chain_IsValid,Lc as b2Chain_SetFriction,Ec as b2Chain_SetRestitution,ce as b2Circle,j2 as b2Clamp,ht as b2ClampFloat,L2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,mi as b2CollideChainSegmentAndCapsule,hi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,ci as b2CollideCircles,bi as b2CollidePolygonAndCapsule,li as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,di as b2CollideSegmentAndCapsule,pi as b2CollideSegmentAndCircle,ui as b2CollideSegmentAndPolygon,V2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Bo as b2CreateBody,qn as b2CreateCapsuleShape,$a as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,yo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,Ka as b2CreateSegmentShape,sh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,_i as b2CreateWorld,Si as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Qb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,Zb as b2DefaultMotorJointDef,tp as b2DefaultMouseJointDef,ep as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,op as b2DefaultWeldJointDef,np as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,Qa as b2DestroyChain,ni as b2DestroyJoint,Ha as b2DestroyShape,Yu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,ue as b2DistanceInput,Ho as b2DistanceJointDef,_l as b2DistanceJoint_EnableLimit,Tl as b2DistanceJoint_EnableMotor,vl as b2DistanceJoint_EnableSpring,wl as b2DistanceJoint_GetCurrentLength,kl as b2DistanceJoint_GetDampingRatio,Pl as b2DistanceJoint_GetHertz,Sl as b2DistanceJoint_GetLength,Cl as b2DistanceJoint_GetMaxLength,Fl as b2DistanceJoint_GetMaxMotorForce,Al as b2DistanceJoint_GetMinLength,El as b2DistanceJoint_GetMotorForce,Ll as b2DistanceJoint_GetMotorSpeed,gl as b2DistanceJoint_IsLimitEnabled,Gl as b2DistanceJoint_IsMotorEnabled,Jl as b2DistanceJoint_IsSpringEnabled,Il as b2DistanceJoint_SetLength,Bl as b2DistanceJoint_SetLengthRange,jl as b2DistanceJoint_SetMaxMotorForce,Rl as b2DistanceJoint_SetMotorSpeed,Dl as b2DistanceJoint_SetSpringDampingRatio,Ml as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,pe as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Zc as b2DynamicTree_GetAreaRatio,sl as b2DynamicTree_GetByteCount,Qc as b2DynamicTree_GetHeight,el as b2DynamicTree_GetMaxBalance,$c as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,ol as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,nl as b2DynamicTree_ShiftOrigin,tl as b2DynamicTree_Validate,uo as b2Filter,nh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,ih as b2GetMilliseconds,ah as b2GetMillisecondsAndReset,we as b2GetSweepTransform,rh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,X2 as b2IntegrateRotation,z2 as b2InvMulRot,Pi as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,Ci as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,rp as b2Joint_GetBodyA,ip as b2Joint_GetBodyB,dp as b2Joint_GetCollideConnected,up as b2Joint_GetConstraintForce,hp as b2Joint_GetConstraintTorque,ap as b2Joint_GetLocalAnchorA,cp as b2Joint_GetLocalAnchorB,sp as b2Joint_GetType,pp as b2Joint_GetUserData,Qu as b2Joint_IsValid,lp as b2Joint_SetCollideConnected,bp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,le as b2LeftPerp,Yt as b2Length,be as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Mi as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Ji as b2Max,P2 as b2MaxFloat,G2 as b2MaxInt,vi as b2Min,D2 as b2MinFloat,T2 as b2MinInt,$o as b2MotorJointDef,ub as b2MotorJoint_GetAngularOffset,Ib as b2MotorJoint_GetCorrectionFactor,bb as b2MotorJoint_GetLinearOffset,mb as b2MotorJoint_GetMaxForce,fb as b2MotorJoint_GetMaxTorque,pb as b2MotorJoint_SetAngularOffset,xb as b2MotorJoint_SetCorrectionFactor,db as b2MotorJoint_SetLinearOffset,hb as b2MotorJoint_SetMaxForce,yb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,kb as b2MouseJoint_GetMaxForce,Db as b2MouseJoint_GetSpringDampingRatio,Jb as b2MouseJoint_GetSpringHertz,wb as b2MouseJoint_GetTarget,Pb as b2MouseJoint_SetMaxForce,Mb as b2MouseJoint_SetSpringDampingRatio,vb as b2MouseJoint_SetSpringHertz,Cb as b2MouseJoint_SetTarget,E2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,H2 as b2MulTransforms,Di as b2NLerp,Ht as b2Neg,dt as b2Normalize,ki as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,$l as b2PrismaticJoint_EnableLimit,od as b2PrismaticJoint_EnableMotor,Wl as b2PrismaticJoint_EnableSpring,Zl as b2PrismaticJoint_GetLowerLimit,cd as b2PrismaticJoint_GetMaxMotorForce,id as b2PrismaticJoint_GetMotorForce,rd as b2PrismaticJoint_GetMotorSpeed,Hl as b2PrismaticJoint_GetSpringDampingRatio,zl as b2PrismaticJoint_GetSpringHertz,td as b2PrismaticJoint_GetUpperLimit,Ql as b2PrismaticJoint_IsLimitEnabled,nd as b2PrismaticJoint_IsMotorEnabled,Ol as b2PrismaticJoint_IsSpringEnabled,ed as b2PrismaticJoint_SetLimits,ad as b2PrismaticJoint_SetMaxMotorForce,sd as b2PrismaticJoint_SetMotorSpeed,Kl as b2PrismaticJoint_SetSpringDampingRatio,Ul as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,ho as b2RevoluteJointDef,gd as b2RevoluteJoint_EnableLimit,vd as b2RevoluteJoint_EnableMotor,md as b2RevoluteJoint_EnableSpring,_d as b2RevoluteJoint_GetAngle,Ad as b2RevoluteJoint_GetLowerLimit,Td as b2RevoluteJoint_GetMaxMotorTorque,Dd as b2RevoluteJoint_GetMotorSpeed,Pd as b2RevoluteJoint_GetMotorTorque,Sd as b2RevoluteJoint_GetSpringDampingRatio,xd as b2RevoluteJoint_GetSpringHertz,Cd as b2RevoluteJoint_GetUpperLimit,Bd as b2RevoluteJoint_IsLimitEnabled,Jd as b2RevoluteJoint_IsMotorEnabled,yd as b2RevoluteJoint_IsSpringEnabled,wd as b2RevoluteJoint_SetLimits,kd as b2RevoluteJoint_SetMaxMotorTorque,Md as b2RevoluteJoint_SetMotorSpeed,Id as b2RevoluteJoint_SetSpringDampingRatio,fd as b2RevoluteJoint_SetSpringHertz,de as b2RightPerp,rt as b2Rot,Y2 as b2Rot_GetAngle,N2 as b2Rot_GetXAxis,W2 as b2Rot_GetYAxis,$2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,oh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,co as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Sc as b2Shape_AreContactEventsEnabled,Ac as b2Shape_AreHitEventsEnabled,gc as b2Shape_ArePreSolveEventsEnabled,xc as b2Shape_AreSensorEventsEnabled,Ic as b2Shape_EnableContactEvents,Bc as b2Shape_EnableHitEvents,_c as b2Shape_EnablePreSolveEvents,fc as b2Shape_EnableSensorEvents,Xc as b2Shape_GetAABB,nc as b2Shape_GetBody,Mc as b2Shape_GetCapsule,Jc as b2Shape_GetChainSegment,wc as b2Shape_GetCircle,qc as b2Shape_GetClosestPoint,jc as b2Shape_GetContactCapacity,Fc as b2Shape_GetContactData,dc as b2Shape_GetDensity,mc as b2Shape_GetFilter,pc as b2Shape_GetFriction,Rc as b2Shape_GetParentChain,Dc as b2Shape_GetPolygon,hc as b2Shape_GetRestitution,vc as b2Shape_GetSegment,Cc as b2Shape_GetType,rc as b2Shape_GetUserData,ic as b2Shape_IsSensor,Hu as b2Shape_IsValid,cc as b2Shape_RayCast,kc as b2Shape_SetCapsule,Pc as b2Shape_SetCircle,lc as b2Shape_SetDensity,yc as b2Shape_SetFilter,bc as b2Shape_SetFriction,Gc as b2Shape_SetPolygon,uc as b2Shape_SetRestitution,Tc as b2Shape_SetSegment,sc as b2Shape_SetUserData,ac as b2Shape_TestPoint,Mn as b2Simplex,ch as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,lo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,wo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Wb as b2WeldJoint_GetAngularDampingRatio,Yb as b2WeldJoint_GetAngularHertz,qb as b2WeldJoint_GetLinearDampingRatio,Fb as b2WeldJoint_GetLinearHertz,Nb as b2WeldJoint_SetAngularDampingRatio,Vb as b2WeldJoint_SetAngularHertz,Xb as b2WeldJoint_SetLinearDampingRatio,jb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Od as b2WheelJoint_EnableLimit,$d as b2WheelJoint_EnableMotor,Xd as b2WheelJoint_EnableSpring,zd as b2WheelJoint_GetLowerLimit,nb as b2WheelJoint_GetMaxMotorTorque,tb as b2WheelJoint_GetMotorSpeed,eb as b2WheelJoint_GetMotorTorque,Wd as b2WheelJoint_GetSpringDampingRatio,Yd as b2WheelJoint_GetSpringHertz,Kd as b2WheelJoint_GetUpperLimit,Ud as b2WheelJoint_IsLimitEnabled,Qd as b2WheelJoint_IsMotorEnabled,qd as b2WheelJoint_IsSpringEnabled,Hd as b2WheelJoint_SetLimits,ob as b2WheelJoint_SetMaxMotorTorque,Zd as b2WheelJoint_SetMotorSpeed,Nd as b2WheelJoint_SetSpringDampingRatio,Vd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,Jo as b2WorldId,h2 as b2World_CastCapsule,u2 as b2World_CastCircle,m2 as b2World_CastPolygon,d2 as b2World_CastRay,b2 as b2World_CastRayClosest,Nu as b2World_Draw,Vh as b2World_DumpMemoryStats,e2 as b2World_EnableContinuous,Zu as b2World_EnableSleeping,t2 as b2World_EnableWarmStarting,S2 as b2World_Explode,Wu as b2World_GetBodyEvents,Uu as b2World_GetContactEvents,qh as b2World_GetCounters,I2 as b2World_GetGravity,Xh as b2World_GetProfile,Ou as b2World_GetSensorEvents,zu as b2World_IsValid,r2 as b2World_OverlapAABB,c2 as b2World_OverlapCapsule,a2 as b2World_OverlapCircle,l2 as b2World_OverlapPolygon,s2 as b2World_SetContactTuning,f2 as b2World_SetCustomFilterCallback,x2 as b2World_SetGravity,n2 as b2World_SetHitEventThreshold,y2 as b2World_SetPreSolveCallback,o2 as b2World_SetRestitutionThreshold,gi as b2World_Step,lh as b2Yield,Wh as mpx,Oh as pxm,or as pxmVec2}; +function Ye(t){let e=Yt(t);if(ee?t:e}function D2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function P2(t,e){return te?t:e}function T2(t){return t<0?-t:t}function G2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function de(t){return new g(-t.y,t.x)}function be(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function R2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function vi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function Ji(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Mi(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function L2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function pe(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function ue(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Di(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function E2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function wi(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function F2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function X2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function q2(t){return Math.atan2(t.s,t.c)}function V2(t){return new g(t.c,t.s)}function Y2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function N2(t,e){return t.c*e.c-t.s*e.s}function W2(t,e){return t.s*e.c+t.c*e.s}function O2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function vo(t){return t<-wo?t+2*wo:t>wo?t-2*wo:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function U2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function z2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function ki(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function Jo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function K2(t){return t&&ae(t.s)&&ae(t.c)&&wi(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function lt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function H2(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Q2=1,x=-1;function Ta(t){Q2=t}function Ga(){return Q2}function Ra(t){}function La(){return new Ti(3,1,0)}var We=1,De=1e5*We,te=2,It=.005*We;var Z2=.25*Math.PI,Qt=4*It,vn=.1*We,th=.5;function eh(){}function oh(){}function nh(){}function sh(){}function rh(){}function ih(t){}function ah(t){}function ch(){}var co=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function lh(t){return t.index1===0}function dh(t){return t.index1!==0}function bh(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function pm(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?de(e):be(e);default:return new g(0,0)}}function mm(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function hh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function mh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function yh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=pm(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=yo(o,Ht(y)),h=o.points[u],m=yo(i,y),f=i.points[m];let v=J(h,f);y=lt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:mh(p);break;case 3:yh(p);break;default:}if(p.count===3)return e;y=mm(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;hh(B,A,p);let w=lt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function xm(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new bo,Object.assign(i.sweepA,o),i.sweepB=new bo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=lt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=lt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=lt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Im(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=yo(t.proxyA,s),c=yo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=yo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=yo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function uh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new he;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=uh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=lt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=ue(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=lt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new lo;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new lo;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new lo;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function Ih(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation||n.isSensor)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(ue(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function fo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function za(t,e,o){return ue(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function Sh(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&xo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ka(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);Sh(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function Ha(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&xo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function mc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function fc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function xc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Ic(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function Sc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function _c(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Bc(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Ac(t){let e=O(t.world0);return Bt(e,t).type}function Cc(t){let e=O(t.world0);return Bt(e,t).circle}function wc(t){let e=O(t.world0);return Bt(e,t).segment}function vc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Jc(t){let e=O(t.world0);return Bt(e,t).capsule}function Mc(t){let e=O(t.world0);return Bt(e,t).polygon}function Dc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Gc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Rc(t,e){let o=ft(t.world0);if(o===null)return;let n=Ih(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Fc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function Xc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new he;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new ho,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,dt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=dt>0?1/dt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Nc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,dt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*dt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(dt*ut-Et*Ge)}for(let ot=0;otdt?dt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var vm=1024;function Bh(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&sl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=lt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Mm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(vm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:gh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:gh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Mm(t,o),o}function Ch(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=il(o.bodyCount),i.contacts=al(o.contactCount),i.joints=cl(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(Io(C.bodySet,y.edges[0].bodyId),Io(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(Io(_.bodySet,y.edges[0].bodyId),Io(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function rl(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function Pm(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,Jo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Tm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Dm(s,r,e):n===yn.b2_stageIntegratePositions&&Pm(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Rm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new bl;N.context=e,N.workerIndex=0,Gm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&Em(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&jm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(_h(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function fl(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function xl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function _l(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Bl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function Al(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=le(o,e.bodyIdA),s=le(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function Cl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function wl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Ml(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function Dl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Pl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Tl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function Rl(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function Ll(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function El(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function jl(t,e){let o=e.distanceJoint,n=le(t,e.bodyIdA),s=le(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=lt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function Fl(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=lt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Xl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=lt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function ql(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=lt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Vl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=lt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Yl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Nl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function $l(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function Zl(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function td(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function ed(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function od(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function sd(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function rd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function id(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ad(t,e){let o=e.bodyIdA,n=le(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=de(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function cd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function dd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=de(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function bd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=de(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function pd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function ud(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function hd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function Id(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=le(e,o.bodyIdA),s=le(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=vo(r),r}function Sd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function _d(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function gd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function Ad(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function Cd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function wd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function vd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Md(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function Dd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Pd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function kd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Td(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Gd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=vo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Rd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function Ld(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=vo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Ed(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function jd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function Fd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Xd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function Od(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function zd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function Kd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Hd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function Zd(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function tb(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function eb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function ob(t,e){let o=e.wheelJoint,n=o.axisA,s=de(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function nb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=de(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function rb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=de(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function ib(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=de(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function ab(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function cb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function lb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-wo,wo)}function bb(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function xb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function Ib(t,e){return t.inv_h*e.motorJoint.angularImpulse}function Sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=vo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function _b(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function gb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=vo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),pe(a.linearImpulse)>w*w&&(a.linearImpulse=lt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Bb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function Ab(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function Cb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Pb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function kb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Tb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Gb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Rb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,lt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function Lb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Eb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Nb(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Wb(t,e){return t.inv_h*e.weldJoint.angularImpulse}function Ob(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Ub(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function zb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Hb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function $b(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function Qb(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function Zb(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new mo;return t.drawSize=.25,t}function tp(){return new tn}function ep(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var Kb=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function Kn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new zn,new zn],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(rl(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p,!0),Lt(t),new Kb(p,h)}function Hn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&xo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=Kn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=lt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=lt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,e.islandId!==x&&Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function op(t){let e=O(t.world0);return Je(e,t).type}function np(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function sp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function rp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function ip(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function ap(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){up(t,i,e);return}let a=null;if(i!==x){a=go(t,i);let d=a.parentIsland;for(;d!==x;){let p=go(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=go(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=go(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?up(t,i,e):up(t,c,e)}function ri(t,e){let o=e.islandId,n=go(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function hp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,Bo(t,e)}function Ys(t,e,o){let n=_t(t,e.edges[0].bodyId),s=_t(t,e.edges[1].bodyId);n.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet?qe(t,s.setIndex):s.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet&&qe(t,n.setIndex);let r=n.islandId,i=s.islandId;if(r===i){hp(t,r,e);return}let c=null;if(r!==x)for(c=go(t,r);c.parentIsland!==x;){let l=go(t,c.parentIsland);l.parentIsland!==x&&(c.parentIsland=l.parentIsland),r=c.parentIsland,c=l}let a=null;if(i!==x)for(a=go(t,i);a.parentIsland!==x;){let l=go(t,a.parentIsland);l.parentIsland!==x&&(a.parentIsland=l.parentIsland),i=a.parentIsland,a=l}c!==a&&c!==null&&a!==null&&(a.parentIsland=r),c!==null?hp(t,r,e):hp(t,i,e),o&&Un(t)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function qm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,Bo(t,o)}function Un(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(qm(t,c),si(t,i))}ii(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;Bo(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}Bo(t,f)}}function Bo(t,e){if(!uo)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function le(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function yp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function fp(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&Bo(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function xp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,xo(t,i,o)}Lt(t)}function Ao(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&yp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}xp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}fp(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function Ip(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function Sp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function _p(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=le(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=Za(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function gp(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ai(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Bp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function Ap(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,Jo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function wp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function vp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Jp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;pe(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Mp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function Dp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Pp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Gp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Rp(t){let e=O(t.world0);return Z(e,t).type}function Lp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}xp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),yp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?_o(o,c,i,u):u.setIndex===M.b2_awakeSet&&(_o(o,i,c,u),_o(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),fp(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?_o(o,i,c,u):(_o(o,i,c,u),_o(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l,!1))}Un(o)}cn(o,n),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Ep(t){let e=O(t.world0);return Z(e,t).userData}function jp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function Fp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Vp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Yp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Np(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Wp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function Op(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function $p(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function Qp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function tu(t){let e=O(t.world0);return Z(e,t).enableSleep}function eu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function ou(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function nu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function su(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;xp(e,o,!0),fp(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];_o(e,i,p,d)}ii(e),Lt(e)}function ru(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let b=e.shapeArray[l];l=b.nextShapeId,Vn(b,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&yp(e,s,o);let d=!1,p=o.headJointKey;for(;p!==x;){let b=p>>1,u=p&1,h=e.jointArray[b];p=h.edges[u].nextKey;let m=e.bodyArray[h.edges[0].bodyId],f=e.bodyArray[h.edges[1].bodyId];if(m.setIndex===M.b2_disabledSet||f.setIndex===M.b2_disabledSet)continue;let y;m.setIndex===M.b2_staticSet&&f.setIndex===M.b2_staticSet?y=M.b2_staticSet:m.setIndex===M.b2_staticSet?y=f.setIndex:y=m.setIndex;let I=e.solverSetArray[y];_o(e,I,n,h),y!==M.b2_staticSet&&Ys(e,h,d)}Un(e),Lt(e)}function iu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function au(t){let e=O(t.world0);return Z(e,t).fixedRotation}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function lu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function du(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function bu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function pu(t){let e=O(t.world0);return Z(e,t).jointCount}function uu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Co=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function il(t){let e=new Es(t);return t>0?(e.data=po(t,()=>new Hs),e):(e.data=null,e)}function al(t){let e=new ln(t);return t>0?(e.data=po(t,()=>new Qn),e):(e.data=null,e)}function cl(t){let e=new dn(t);return t>0?(e.data=po(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=po(Co,()=>new Hs),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=po(Co,()=>new Pt),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=po(Co,()=>new Qn),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=po(Co,()=>new Ws),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=po(Co,()=>new Os),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ci(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),hu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function Su(t,e,o){let n=J(e,t),s=lt(n),r=be(s),i=new ge;return i.vertices=[t,e],i.centroid=$t(t,e,.5),i.normals=[r,Ht(r)],i.count=2,i.radius=o,i}function li(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function di(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;vi(e.p,1,K(e.q,r),hu.p),hu.q=e.q,Uo(hu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=ue(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let dt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let dt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let dt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);dt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);dt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,dt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+dt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;vi(D,.5*(R-X-P),b,pt),vi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function kh(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),mu=new g,yu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;mu.x=e.p.x+(e.q.c*r-e.q.s*i),mu.y=e.p.y+(e.q.s*r+e.q.c*i),yu.p=mu,yu.q=e.q,Uo(yu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else Ph(kt,Ut,a,p,h,s)}else Ph(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function yi(t,e,o,n,s,r){let i=Su(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function fu(t,e,o,n,s,r,i,c,a,l){let d=de(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function xu(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var Iu=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=lt(J(l,a)),p=new Iu;p.edge1=d.clone();let b=.01,u=lt(J(a,t.ghost1));p.normal0=be(u),p.convex1=z(u,d)>=b;let h=lt(J(t.ghost2,l));p.normal2=be(h),p.convex2=z(d,h)>=b;let m=be(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=lt(J(et,W)),ot=xu(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=xu(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new gu)),Th=!1;function Nm(t,e,o,n,s,r){return li(t.circle,e,o.circle,n,r)}function Wm(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function Um(t,e,o,n,s,r){return di(t.polygon,e,o.circle,n,r)}function zm(t,e,o,n,s,r){return pi(t.polygon,e,o.capsule,n,r)}function Km(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function Hm(t,e,o,n,s,r){return ui(t.segment,e,o.circle,n,r)}function $m(t,e,o,n,s,r){return bi(t.segment,e,o.capsule,n,r)}function Qm(t,e,o,n,s,r){return hi(t.segment,e,o.polygon,n,r)}function Zm(t,e,o,n,s,r){return mi(t.chainSegment,e,o.circle,n,r)}function ty(t,e,o,n,s,r){return yi(t.chainSegment,e,o.capsule,n,s,r)}function ey(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Bu(){Th===!1&&(Ve(Nm,Y.b2_circleShape,Y.b2_circleShape),Ve(Wm,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(Um,Y.b2_polygonShape,Y.b2_circleShape),Ve(zm,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Km,Y.b2_polygonShape,Y.b2_polygonShape),Ve(Hm,Y.b2_segmentShape,Y.b2_circleShape),Ve($m,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(Zm,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_polygonShape),Th=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Vm(e.friction,o.friction),h.restitution=Ym(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function xo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function oy(t,e,o,n,s){let r=new he;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var _u=new To;function Au(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=oy(o,n,r,i,e.cache);else{e.manifold.copyTo(_u);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Ju=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Mu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function ny(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew wu),sy(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function sy(t,e,o){let n=o.broadPhase,s=new vu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,cy(s),s.dt>0&&ul(n,s),n.locked=!1}var An=new g,ts=new g,ly=new rt,Ru=new at(An,ly);function Lh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;U2(s,r.center,Ru),e.image?t.DrawImageCircle(Ru,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Ru,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var ju=class{constructor(e,o){this.world=e,this.draw=o}};function dy(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Lh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function by(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new ju(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Rh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Rh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=be(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Vu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){by(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Lh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=be(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Yu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Nu(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Wu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function Ou(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function Qu(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function Zu(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function t2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function e2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function o2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function py(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var Fu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function n2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new Fu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function r2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Si;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function c2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Qa(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=lt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function x2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Xu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,hy,r)}function Lu(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function ii(t){if(!uo)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=Lu(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=Lu(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!uo)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Fh(){}function Xh(){}function qh(){}var kg=new g;var I2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Ai({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new I2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new mo;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{_2(e,o)})}function _2(t,e){let o=ai(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function $h(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=B2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=g2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t){let e=t.worldDef;return e||(e=lr()),_i(),{worldId:gi(e)}}var Ja=0;function tm(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=le(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=fo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function nm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function A2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function sm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ci(t){let e=t.jointDef;return e||(e=new mo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function rm(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function im(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var yA=0,fA=1,xA=2;export{Oh as AddSpriteToWorld,bh as B2_ID_EQUALS,dh as B2_IS_NON_NULL,lh as B2_IS_NULL,x as B2_NULL_INDEX,_2 as BodyToSprite,zh as ClearWorldSprites,B2 as CreateBoxPolygon,Ai as CreateCapsule,em as CreateChain,g2 as CreateCircle,im as CreateDistanceJoint,lm as CreateMotorJoint,dm as CreateMouseJoint,om as CreateNGonPolygon,sm as CreatePhysicsEditorShape,va as CreatePolygon,nm as CreatePolygonFromEarcut,A2 as CreatePolygonFromVertices,cm as CreatePrismaticJoint,Ci as CreateRevoluteJoint,rm as CreateWeldJoint,am as CreateWheelJoint,Zh as CreateWorld,xA as DYNAMIC,Kh as GetBodyFromSprite,Yh as GetWorldScale,fA as KINEMATIC,Ca as Ragdoll,Uh as RemoveSpriteFromWorld,wa as RotFromRad,yA as STATIC,Vh as SetWorldScale,Aa as Skeletons,$h as SpriteToBox,Qh as SpriteToCircle,Hh as UpdateWorldSprites,tm as WorldStep,xt as b2AABB,Le as b2AABB_Center,Jo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,D2 as b2AbsFloat,T2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Gp as b2Body_ApplyAngularImpulse,Dp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,kp as b2Body_ApplyLinearImpulse,Tp as b2Body_ApplyLinearImpulseToCenter,Np as b2Body_ApplyMassFromShapes,Pp as b2Body_ApplyTorque,_p as b2Body_ComputeAABB,su as b2Body_Disable,ru as b2Body_Enable,du as b2Body_EnableHitEvents,nu as b2Body_EnableSleep,zp as b2Body_GetAngularDamping,vp as b2Body_GetAngularVelocity,Ip as b2Body_GetContactCapacity,Sp as b2Body_GetContactData,Hp as b2Body_GetGravityScale,pu as b2Body_GetJointCount,uu as b2Body_GetJoints,Op as b2Body_GetLinearDamping,wp as b2Body_GetLinearVelocity,Xp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,Ap as b2Body_GetLocalVector,jp as b2Body_GetMass,Yp as b2Body_GetMassData,gp as b2Body_GetPosition,Us as b2Body_GetRotation,Fp as b2Body_GetRotationalInertia,bu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,ou as b2Body_GetSleepThreshold,ai as b2Body_GetTransform,Rp as b2Body_GetType,Ep as b2Body_GetUserData,qp as b2Body_GetWorldCenterOfMass,Bp as b2Body_GetWorldPoint,Cp as b2Body_GetWorldVector,$p as b2Body_IsAwake,lu as b2Body_IsBullet,Zp as b2Body_IsEnabled,au as b2Body_IsFixedRotation,tu as b2Body_IsSleepEnabled,Uu as b2Body_IsValid,Up as b2Body_SetAngularDamping,Mp as b2Body_SetAngularVelocity,Qp as b2Body_SetAwake,cu as b2Body_SetBullet,iu as b2Body_SetFixedRotation,Kp as b2Body_SetGravityScale,Wp as b2Body_SetLinearDamping,Jp as b2Body_SetLinearVelocity,Vp as b2Body_SetMassData,eu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,Lp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,Ku as b2Chain_IsValid,Rc as b2Chain_SetFriction,Lc as b2Chain_SetRestitution,ce as b2Circle,L2 as b2Clamp,ht as b2ClampFloat,G2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,yi as b2CollideChainSegmentAndCapsule,mi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,li as b2CollideCircles,pi as b2CollidePolygonAndCapsule,di as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,bi as b2CollideSegmentAndCapsule,ui as b2CollideSegmentAndCircle,hi as b2CollideSegmentAndPolygon,X2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Ao as b2CreateBody,qn as b2CreateCapsuleShape,Ha as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,fo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,za as b2CreateSegmentShape,nh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,gi as b2CreateWorld,_i as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Hb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,$b as b2DefaultMotorJointDef,Qb as b2DefaultMouseJointDef,Zb as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,tp as b2DefaultWeldJointDef,ep as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,$a as b2DestroyChain,ni as b2DestroyJoint,Ka as b2DestroyShape,qu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,he as b2DistanceInput,Ho as b2DistanceJointDef,Il as b2DistanceJoint_EnableLimit,Pl as b2DistanceJoint_EnableMotor,Cl as b2DistanceJoint_EnableSpring,Al as b2DistanceJoint_GetCurrentLength,xl as b2DistanceJoint_GetLength,Bl as b2DistanceJoint_GetMaxLength,El as b2DistanceJoint_GetMaxMotorForce,gl as b2DistanceJoint_GetMinLength,Rl as b2DistanceJoint_GetMotorForce,Gl as b2DistanceJoint_GetMotorSpeed,Dl as b2DistanceJoint_GetSpringDampingRatio,Ml as b2DistanceJoint_GetSpringHertz,Sl as b2DistanceJoint_IsLimitEnabled,kl as b2DistanceJoint_IsMotorEnabled,wl as b2DistanceJoint_IsSpringEnabled,fl as b2DistanceJoint_SetLength,_l as b2DistanceJoint_SetLengthRange,Ll as b2DistanceJoint_SetMaxMotorForce,Tl as b2DistanceJoint_SetMotorSpeed,Jl as b2DistanceJoint_SetSpringDampingRatio,vl as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,ue as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Qc as b2DynamicTree_GetAreaRatio,nl as b2DynamicTree_GetByteCount,$c as b2DynamicTree_GetHeight,tl as b2DynamicTree_GetMaxBalance,Hc as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,el as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,ol as b2DynamicTree_ShiftOrigin,Zc as b2DynamicTree_Validate,ho as b2Filter,oh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,rh as b2GetMilliseconds,ih as b2GetMillisecondsAndReset,we as b2GetSweepTransform,sh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,j2 as b2IntegrateRotation,O2 as b2InvMulRot,ki as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,wi as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,np as b2Joint_GetBodyA,sp as b2Joint_GetBodyB,cp as b2Joint_GetCollideConnected,bp as b2Joint_GetConstraintForce,pp as b2Joint_GetConstraintTorque,rp as b2Joint_GetLocalAnchorA,ip as b2Joint_GetLocalAnchorB,op as b2Joint_GetType,dp as b2Joint_GetUserData,Hu as b2Joint_IsValid,ap as b2Joint_SetCollideConnected,lp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,de as b2LeftPerp,Yt as b2Length,pe as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Di as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Mi as b2Max,M2 as b2MaxFloat,k2 as b2MaxInt,Ji as b2Min,J2 as b2MinFloat,P2 as b2MinInt,$o as b2MotorJointDef,bb as b2MotorJoint_GetAngularOffset,fb as b2MotorJoint_GetCorrectionFactor,lb as b2MotorJoint_GetLinearOffset,ub as b2MotorJoint_GetMaxForce,mb as b2MotorJoint_GetMaxTorque,db as b2MotorJoint_SetAngularOffset,yb as b2MotorJoint_SetCorrectionFactor,cb as b2MotorJoint_SetLinearOffset,pb as b2MotorJoint_SetMaxForce,hb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,Db as b2MouseJoint_GetMaxForce,Jb as b2MouseJoint_GetSpringDampingRatio,wb as b2MouseJoint_GetSpringHertz,Ab as b2MouseJoint_GetTarget,Mb as b2MouseJoint_SetMaxForce,vb as b2MouseJoint_SetSpringDampingRatio,Cb as b2MouseJoint_SetSpringHertz,Bb as b2MouseJoint_SetTarget,R2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,z2 as b2MulTransforms,Pi as b2NLerp,Ht as b2Neg,lt as b2Normalize,H2 as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,Kl as b2PrismaticJoint_EnableLimit,td as b2PrismaticJoint_EnableMotor,Yl as b2PrismaticJoint_EnableSpring,$l as b2PrismaticJoint_GetLowerLimit,id as b2PrismaticJoint_GetMaxMotorForce,sd as b2PrismaticJoint_GetMotorForce,nd as b2PrismaticJoint_GetMotorSpeed,zl as b2PrismaticJoint_GetSpringDampingRatio,Ol as b2PrismaticJoint_GetSpringHertz,Ql as b2PrismaticJoint_GetUpperLimit,Hl as b2PrismaticJoint_IsLimitEnabled,ed as b2PrismaticJoint_IsMotorEnabled,Nl as b2PrismaticJoint_IsSpringEnabled,Zl as b2PrismaticJoint_SetLimits,rd as b2PrismaticJoint_SetMaxMotorForce,od as b2PrismaticJoint_SetMotorSpeed,Ul as b2PrismaticJoint_SetSpringDampingRatio,Wl as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,mo as b2RevoluteJointDef,Sd as b2RevoluteJoint_EnableLimit,Cd as b2RevoluteJoint_EnableMotor,ud as b2RevoluteJoint_EnableSpring,Id as b2RevoluteJoint_GetAngle,gd as b2RevoluteJoint_GetLowerLimit,Pd as b2RevoluteJoint_GetMaxMotorTorque,Jd as b2RevoluteJoint_GetMotorSpeed,Md as b2RevoluteJoint_GetMotorTorque,xd as b2RevoluteJoint_GetSpringDampingRatio,yd as b2RevoluteJoint_GetSpringHertz,Bd as b2RevoluteJoint_GetUpperLimit,_d as b2RevoluteJoint_IsLimitEnabled,wd as b2RevoluteJoint_IsMotorEnabled,hd as b2RevoluteJoint_IsSpringEnabled,Ad as b2RevoluteJoint_SetLimits,Dd as b2RevoluteJoint_SetMaxMotorTorque,vd as b2RevoluteJoint_SetMotorSpeed,fd as b2RevoluteJoint_SetSpringDampingRatio,md as b2RevoluteJoint_SetSpringHertz,be as b2RightPerp,rt as b2Rot,q2 as b2Rot_GetAngle,V2 as b2Rot_GetXAxis,Y2 as b2Rot_GetYAxis,K2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,eh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,lo as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Ic as b2Shape_AreContactEventsEnabled,Bc as b2Shape_AreHitEventsEnabled,_c as b2Shape_ArePreSolveEventsEnabled,fc as b2Shape_AreSensorEventsEnabled,xc as b2Shape_EnableContactEvents,gc as b2Shape_EnableHitEvents,Sc as b2Shape_EnablePreSolveEvents,yc as b2Shape_EnableSensorEvents,Fc as b2Shape_GetAABB,oc as b2Shape_GetBody,Jc as b2Shape_GetCapsule,vc as b2Shape_GetChainSegment,Cc as b2Shape_GetCircle,Xc as b2Shape_GetClosestPoint,Ec as b2Shape_GetContactCapacity,jc as b2Shape_GetContactData,lc as b2Shape_GetDensity,hc as b2Shape_GetFilter,bc as b2Shape_GetFriction,Gc as b2Shape_GetParentChain,Mc as b2Shape_GetPolygon,uc as b2Shape_GetRestitution,wc as b2Shape_GetSegment,Ac as b2Shape_GetType,sc as b2Shape_GetUserData,rc as b2Shape_IsSensor,zu as b2Shape_IsValid,ac as b2Shape_RayCast,Pc as b2Shape_SetCapsule,Dc as b2Shape_SetCircle,cc as b2Shape_SetDensity,mc as b2Shape_SetFilter,dc as b2Shape_SetFriction,Tc as b2Shape_SetPolygon,pc as b2Shape_SetRestitution,kc as b2Shape_SetSegment,nc as b2Shape_SetUserData,ic as b2Shape_TestPoint,Mn as b2Simplex,ah as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,bo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,vo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Yb as b2WeldJoint_GetAngularDampingRatio,qb as b2WeldJoint_GetAngularHertz,Fb as b2WeldJoint_GetLinearDampingRatio,Eb as b2WeldJoint_GetLinearHertz,Vb as b2WeldJoint_SetAngularDampingRatio,Xb as b2WeldJoint_SetAngularHertz,jb as b2WeldJoint_SetLinearDampingRatio,Lb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Nd as b2WheelJoint_EnableLimit,Kd as b2WheelJoint_EnableMotor,jd as b2WheelJoint_EnableSpring,Od as b2WheelJoint_GetLowerLimit,eb as b2WheelJoint_GetMaxMotorTorque,Qd as b2WheelJoint_GetMotorSpeed,Zd as b2WheelJoint_GetMotorTorque,Yd as b2WheelJoint_GetSpringDampingRatio,qd as b2WheelJoint_GetSpringHertz,Ud as b2WheelJoint_GetUpperLimit,Wd as b2WheelJoint_IsLimitEnabled,Hd as b2WheelJoint_IsMotorEnabled,Fd as b2WheelJoint_IsSpringEnabled,zd as b2WheelJoint_SetLimits,tb as b2WheelJoint_SetMaxMotorTorque,$d as b2WheelJoint_SetMotorSpeed,Vd as b2WheelJoint_SetSpringDampingRatio,Xd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,co as b2WorldId,p2 as b2World_CastCapsule,b2 as b2World_CastCircle,u2 as b2World_CastPolygon,c2 as b2World_CastRay,l2 as b2World_CastRayClosest,Vu as b2World_Draw,qh as b2World_DumpMemoryStats,Zu as b2World_EnableContinuous,$u as b2World_EnableSleeping,Qu as b2World_EnableWarmStarting,x2 as b2World_Explode,Yu as b2World_GetBodyEvents,Wu as b2World_GetContactEvents,Xh as b2World_GetCounters,f2 as b2World_GetGravity,Fh as b2World_GetProfile,Nu as b2World_GetSensorEvents,Ou as b2World_IsValid,n2 as b2World_OverlapAABB,i2 as b2World_OverlapCapsule,r2 as b2World_OverlapCircle,a2 as b2World_OverlapPolygon,o2 as b2World_SetContactTuning,m2 as b2World_SetCustomFilterCallback,y2 as b2World_SetGravity,e2 as b2World_SetHitEventThreshold,h2 as b2World_SetPreSolveCallback,t2 as b2World_SetRestitutionThreshold,Bi as b2World_Step,ch as b2Yield,Nh as mpx,Wh as pxm,or as pxmVec2}; diff --git a/src/shape_c.js b/src/shape_c.js index df3bea9..9f0bcb0 100644 --- a/src/shape_c.js +++ b/src/shape_c.js @@ -1785,7 +1785,7 @@ export function b2Shape_GetParentChain(shapeId) * @param {b2ChainId} chainId - The identifier for the chain * @returns {b2WorldId} */ -export function b2Chain_GetWorld( b2ChainId chainId ) +export function b2Chain_GetWorld(chainId) { const world = b2GetWorld(chainId.world0); return new b2WorldId(chainId.world0 + 1, world.revision); From c380562730d9483d536ba68958928a411317077d Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 14 Jan 2025 17:40:24 -0800 Subject: [PATCH 08/14] update CHANGELOG and expose b2World_IsSleepingEnabled --- CHANGELOG.md | 8 ++++---- dist/PhaserBox2D-Debug.js | 2 +- dist/PhaserBox2D-Debug.js.map | 4 ++-- dist/PhaserBox2D-Render.js | 2 +- dist/PhaserBox2D-Render.js.map | 4 ++-- dist/PhaserBox2D.js | 2 +- dist/PhaserBox2D.min.js | 4 ++-- src/include/world_h.js | 1 + 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b9548b..4894b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,13 +64,13 @@ We're happy to consider a commit as fully completed even if it has asserts or co | ✔️ | [8e7a17c](https://github.com/erincatto/box2d/commit/8e7a17c5c942dbf2fdea8b9d09983410dcc0429d) | Update README.md | Done | | ✔️ | [2b880d1](https://github.com/erincatto/box2d/commit/2b880d1264f1493f50bee3906b7d48ecdae4fc6e) | Fix null being passed to memcpy (#770) | Done | | ✔️ | [0e333ff](https://github.com/erincatto/box2d/commit/0e333fff0669afac5d9416e21f22adccada11755) | Custom SSE2 and Neon (#772) | Done | -| 🔎 | [9314f30](https://github.com/erincatto/box2d/commit/9314f303a7cdd6171f7ae06cd1bbf110efffe3cc) | Cross platform determinism (#773) | Pending | +| 🔎 | [9314f30](https://github.com/erincatto/box2d/commit/9314f303a7cdd6171f7ae06cd1bbf110efffe3cc) | Cross platform determinism (#773) | Done - skipped custom trig functions (unneeded for determinism in js) | | ✔️ | [5fdbbc8](https://github.com/erincatto/box2d/commit/5fdbbc815684421513faebee10e20aad6e8b6365) | Misc Issues (#783) | Done | | ✔️ | [e6cbbfc](https://github.com/erincatto/box2d/commit/e6cbbfc85eb781f36dbcea316c355fb4748dabff) | Linux gcc fixes (#784) | Done | -| 🔎 | [d323a0e](https://github.com/erincatto/box2d/commit/d323a0e7cebb8bdcd63ebc600107b577225c521f) | Cross platform random numbers for samples (#785) | TODO: b2Shape_RayCast now uses b2RayCastInput | -| 🔎 | [c69eee4](https://github.com/erincatto/box2d/commit/c69eee4b2f76a19d8b556c92fcd64c742879fc52) | Update AMD benchmarks (#787) | TODO: IsSleepingEnabled | +| 🔎 | [d323a0e](https://github.com/erincatto/box2d/commit/d323a0e7cebb8bdcd63ebc600107b577225c521f) | Cross platform random numbers for samples (#785) | Done | +| 🔎 | [c69eee4](https://github.com/erincatto/box2d/commit/c69eee4b2f76a19d8b556c92fcd64c742879fc52) | Update AMD benchmarks (#787) | Done | | 🔎 | [c56a76d](https://github.com/erincatto/box2d/commit/c56a76daa50726d2e47aad6bb648473ee14d822e) | Array refactor (#796) | Pending | -| 🔎 | [df7373c](https://github.com/erincatto/box2d/commit/df7373c08a41b7a4ba6edd5d4be200675a948176) | New capsule collider (#804) | Pending | +| 🔎 | [df7373c](https://github.com/erincatto/box2d/commit/df7373c08a41b7a4ba6edd5d4be200675a948176) | New capsule collider (#804) | Done | | 🔎 | [67b9835](https://github.com/erincatto/box2d/commit/67b98356074805ffdf43160a18390dd76b6bf550) | Fix missing hit events (#808) | Pending | | 🔎 | [e7cb9f0](https://github.com/erincatto/box2d/commit/e7cb9f0b80420a865f11c0bbf37c3ebbe31629d2) | Explosion features (#810) | Pending | | 🔎 | [b864f53](https://github.com/erincatto/box2d/commit/b864f533c3d851d5c7b55fd6fb4bac00466ff854) | Friction and restitution mixing rules (#811) | Pending | diff --git a/dist/PhaserBox2D-Debug.js b/dist/PhaserBox2D-Debug.js index f0c7d5b..ddc28b1 100644 --- a/dist/PhaserBox2D-Debug.js +++ b/dist/PhaserBox2D-Debug.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:14 + * Tuesday, 14 January 2025 at 17:39 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D-Debug.js.map b/dist/PhaserBox2D-Debug.js.map index 6ca0730..150296d 100644 --- a/dist/PhaserBox2D-Debug.js.map +++ b/dist/PhaserBox2D-Debug.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": "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", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D-Render.js b/dist/PhaserBox2D-Render.js index c3718fe..3e3a55f 100644 --- a/dist/PhaserBox2D-Render.js +++ b/dist/PhaserBox2D-Render.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:14 + * Tuesday, 14 January 2025 at 17:39 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D-Render.js.map b/dist/PhaserBox2D-Render.js.map index ef759af..61e249d 100644 --- a/dist/PhaserBox2D-Render.js.map +++ b/dist/PhaserBox2D-Render.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": "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", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D.js b/dist/PhaserBox2D.js index b3315a1..b68aa07 100644 --- a/dist/PhaserBox2D.js +++ b/dist/PhaserBox2D.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:14 + * Tuesday, 14 January 2025 at 17:39 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D.min.js b/dist/PhaserBox2D.min.js index e9147c3..2568dc1 100644 --- a/dist/PhaserBox2D.min.js +++ b/dist/PhaserBox2D.min.js @@ -1,11 +1,11 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:14 + * Tuesday, 14 January 2025 at 17:39 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is * Copyright 2025 Phaser Studio Inc and is released under the MIT license. */ -function Ye(t){let e=Yt(t);if(ee?t:e}function D2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function P2(t,e){return te?t:e}function T2(t){return t<0?-t:t}function G2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function de(t){return new g(-t.y,t.x)}function be(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function R2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function vi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function Ji(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Mi(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function L2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function pe(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function ue(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Di(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function E2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function wi(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function F2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function X2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function q2(t){return Math.atan2(t.s,t.c)}function V2(t){return new g(t.c,t.s)}function Y2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function N2(t,e){return t.c*e.c-t.s*e.s}function W2(t,e){return t.s*e.c+t.c*e.s}function O2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function vo(t){return t<-wo?t+2*wo:t>wo?t-2*wo:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function U2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function z2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function ki(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function Jo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function K2(t){return t&&ae(t.s)&&ae(t.c)&&wi(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function lt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function H2(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Q2=1,x=-1;function Ta(t){Q2=t}function Ga(){return Q2}function Ra(t){}function La(){return new Ti(3,1,0)}var We=1,De=1e5*We,te=2,It=.005*We;var Z2=.25*Math.PI,Qt=4*It,vn=.1*We,th=.5;function eh(){}function oh(){}function nh(){}function sh(){}function rh(){}function ih(t){}function ah(t){}function ch(){}var co=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function lh(t){return t.index1===0}function dh(t){return t.index1!==0}function bh(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function pm(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?de(e):be(e);default:return new g(0,0)}}function mm(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function hh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function mh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function yh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=pm(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=yo(o,Ht(y)),h=o.points[u],m=yo(i,y),f=i.points[m];let v=J(h,f);y=lt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:mh(p);break;case 3:yh(p);break;default:}if(p.count===3)return e;y=mm(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;hh(B,A,p);let w=lt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function xm(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new bo,Object.assign(i.sweepA,o),i.sweepB=new bo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=lt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=lt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=lt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Im(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=yo(t.proxyA,s),c=yo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=yo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=yo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function uh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new he;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=uh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=lt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=ue(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=lt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new lo;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new lo;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new lo;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function Ih(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation||n.isSensor)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(ue(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function fo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function za(t,e,o){return ue(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function Sh(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&xo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ka(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);Sh(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function Ha(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&xo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function mc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function fc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function xc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Ic(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function Sc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function _c(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Bc(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Ac(t){let e=O(t.world0);return Bt(e,t).type}function Cc(t){let e=O(t.world0);return Bt(e,t).circle}function wc(t){let e=O(t.world0);return Bt(e,t).segment}function vc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Jc(t){let e=O(t.world0);return Bt(e,t).capsule}function Mc(t){let e=O(t.world0);return Bt(e,t).polygon}function Dc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Gc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Rc(t,e){let o=ft(t.world0);if(o===null)return;let n=Ih(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Fc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function Xc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new he;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new ho,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,dt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=dt>0?1/dt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Nc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,dt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*dt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(dt*ut-Et*Ge)}for(let ot=0;otdt?dt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var vm=1024;function Bh(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&sl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=lt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Mm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(vm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:gh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:gh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Mm(t,o),o}function Ch(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=il(o.bodyCount),i.contacts=al(o.contactCount),i.joints=cl(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(Io(C.bodySet,y.edges[0].bodyId),Io(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(Io(_.bodySet,y.edges[0].bodyId),Io(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function rl(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function Pm(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,Jo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Tm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Dm(s,r,e):n===yn.b2_stageIntegratePositions&&Pm(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Rm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new bl;N.context=e,N.workerIndex=0,Gm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&Em(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&jm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(_h(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function fl(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function xl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function _l(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Bl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function Al(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=le(o,e.bodyIdA),s=le(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function Cl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function wl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Ml(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function Dl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Pl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Tl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function Rl(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function Ll(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function El(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function jl(t,e){let o=e.distanceJoint,n=le(t,e.bodyIdA),s=le(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=lt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function Fl(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=lt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Xl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=lt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function ql(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=lt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Vl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=lt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Yl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Nl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function $l(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function Zl(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function td(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function ed(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function od(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function sd(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function rd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function id(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ad(t,e){let o=e.bodyIdA,n=le(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=de(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function cd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function dd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=de(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function bd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=de(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function pd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function ud(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function hd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function Id(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=le(e,o.bodyIdA),s=le(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=vo(r),r}function Sd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function _d(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function gd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function Ad(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function Cd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function wd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function vd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Md(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function Dd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Pd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function kd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Td(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Gd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=vo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Rd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function Ld(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=vo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Ed(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function jd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function Fd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Xd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function Od(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function zd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function Kd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Hd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function Zd(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function tb(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function eb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function ob(t,e){let o=e.wheelJoint,n=o.axisA,s=de(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function nb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=de(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function rb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=de(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function ib(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=de(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function ab(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function cb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function lb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-wo,wo)}function bb(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function xb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function Ib(t,e){return t.inv_h*e.motorJoint.angularImpulse}function Sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=vo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function _b(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function gb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=vo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),pe(a.linearImpulse)>w*w&&(a.linearImpulse=lt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Bb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function Ab(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function Cb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Pb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function kb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Tb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Gb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Rb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,lt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function Lb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Eb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Nb(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Wb(t,e){return t.inv_h*e.weldJoint.angularImpulse}function Ob(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Ub(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function zb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Hb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function $b(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function Qb(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function Zb(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new mo;return t.drawSize=.25,t}function tp(){return new tn}function ep(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var Kb=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function Kn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new zn,new zn],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(rl(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p,!0),Lt(t),new Kb(p,h)}function Hn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&xo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=Kn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=lt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=lt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,e.islandId!==x&&Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function op(t){let e=O(t.world0);return Je(e,t).type}function np(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function sp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function rp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function ip(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function ap(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){up(t,i,e);return}let a=null;if(i!==x){a=go(t,i);let d=a.parentIsland;for(;d!==x;){let p=go(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=go(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=go(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?up(t,i,e):up(t,c,e)}function ri(t,e){let o=e.islandId,n=go(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function hp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,Bo(t,e)}function Ys(t,e,o){let n=_t(t,e.edges[0].bodyId),s=_t(t,e.edges[1].bodyId);n.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet?qe(t,s.setIndex):s.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet&&qe(t,n.setIndex);let r=n.islandId,i=s.islandId;if(r===i){hp(t,r,e);return}let c=null;if(r!==x)for(c=go(t,r);c.parentIsland!==x;){let l=go(t,c.parentIsland);l.parentIsland!==x&&(c.parentIsland=l.parentIsland),r=c.parentIsland,c=l}let a=null;if(i!==x)for(a=go(t,i);a.parentIsland!==x;){let l=go(t,a.parentIsland);l.parentIsland!==x&&(a.parentIsland=l.parentIsland),i=a.parentIsland,a=l}c!==a&&c!==null&&a!==null&&(a.parentIsland=r),c!==null?hp(t,r,e):hp(t,i,e),o&&Un(t)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function qm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,Bo(t,o)}function Un(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(qm(t,c),si(t,i))}ii(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;Bo(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}Bo(t,f)}}function Bo(t,e){if(!uo)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function le(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function yp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function fp(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&Bo(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function xp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,xo(t,i,o)}Lt(t)}function Ao(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&yp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}xp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}fp(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function Ip(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function Sp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function _p(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=le(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=Za(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function gp(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ai(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Bp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function Ap(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,Jo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function wp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function vp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Jp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;pe(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Mp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function Dp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Pp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Gp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Rp(t){let e=O(t.world0);return Z(e,t).type}function Lp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}xp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),yp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?_o(o,c,i,u):u.setIndex===M.b2_awakeSet&&(_o(o,i,c,u),_o(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),fp(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?_o(o,i,c,u):(_o(o,i,c,u),_o(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l,!1))}Un(o)}cn(o,n),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Ep(t){let e=O(t.world0);return Z(e,t).userData}function jp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function Fp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Vp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Yp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Np(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Wp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function Op(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function $p(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function Qp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function tu(t){let e=O(t.world0);return Z(e,t).enableSleep}function eu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function ou(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function nu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function su(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;xp(e,o,!0),fp(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];_o(e,i,p,d)}ii(e),Lt(e)}function ru(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let b=e.shapeArray[l];l=b.nextShapeId,Vn(b,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&yp(e,s,o);let d=!1,p=o.headJointKey;for(;p!==x;){let b=p>>1,u=p&1,h=e.jointArray[b];p=h.edges[u].nextKey;let m=e.bodyArray[h.edges[0].bodyId],f=e.bodyArray[h.edges[1].bodyId];if(m.setIndex===M.b2_disabledSet||f.setIndex===M.b2_disabledSet)continue;let y;m.setIndex===M.b2_staticSet&&f.setIndex===M.b2_staticSet?y=M.b2_staticSet:m.setIndex===M.b2_staticSet?y=f.setIndex:y=m.setIndex;let I=e.solverSetArray[y];_o(e,I,n,h),y!==M.b2_staticSet&&Ys(e,h,d)}Un(e),Lt(e)}function iu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function au(t){let e=O(t.world0);return Z(e,t).fixedRotation}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function lu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function du(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function bu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function pu(t){let e=O(t.world0);return Z(e,t).jointCount}function uu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Co=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function il(t){let e=new Es(t);return t>0?(e.data=po(t,()=>new Hs),e):(e.data=null,e)}function al(t){let e=new ln(t);return t>0?(e.data=po(t,()=>new Qn),e):(e.data=null,e)}function cl(t){let e=new dn(t);return t>0?(e.data=po(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=po(Co,()=>new Hs),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=po(Co,()=>new Pt),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=po(Co,()=>new Qn),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=po(Co,()=>new Ws),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=po(Co,()=>new Os),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ci(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),hu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function Su(t,e,o){let n=J(e,t),s=lt(n),r=be(s),i=new ge;return i.vertices=[t,e],i.centroid=$t(t,e,.5),i.normals=[r,Ht(r)],i.count=2,i.radius=o,i}function li(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function di(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;vi(e.p,1,K(e.q,r),hu.p),hu.q=e.q,Uo(hu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=ue(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let dt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let dt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let dt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);dt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);dt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,dt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+dt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;vi(D,.5*(R-X-P),b,pt),vi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function kh(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),mu=new g,yu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;mu.x=e.p.x+(e.q.c*r-e.q.s*i),mu.y=e.p.y+(e.q.s*r+e.q.c*i),yu.p=mu,yu.q=e.q,Uo(yu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else Ph(kt,Ut,a,p,h,s)}else Ph(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function yi(t,e,o,n,s,r){let i=Su(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function fu(t,e,o,n,s,r,i,c,a,l){let d=de(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function xu(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var Iu=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=lt(J(l,a)),p=new Iu;p.edge1=d.clone();let b=.01,u=lt(J(a,t.ghost1));p.normal0=be(u),p.convex1=z(u,d)>=b;let h=lt(J(t.ghost2,l));p.normal2=be(h),p.convex2=z(d,h)>=b;let m=be(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=lt(J(et,W)),ot=xu(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=xu(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new gu)),Th=!1;function Nm(t,e,o,n,s,r){return li(t.circle,e,o.circle,n,r)}function Wm(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function Um(t,e,o,n,s,r){return di(t.polygon,e,o.circle,n,r)}function zm(t,e,o,n,s,r){return pi(t.polygon,e,o.capsule,n,r)}function Km(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function Hm(t,e,o,n,s,r){return ui(t.segment,e,o.circle,n,r)}function $m(t,e,o,n,s,r){return bi(t.segment,e,o.capsule,n,r)}function Qm(t,e,o,n,s,r){return hi(t.segment,e,o.polygon,n,r)}function Zm(t,e,o,n,s,r){return mi(t.chainSegment,e,o.circle,n,r)}function ty(t,e,o,n,s,r){return yi(t.chainSegment,e,o.capsule,n,s,r)}function ey(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Bu(){Th===!1&&(Ve(Nm,Y.b2_circleShape,Y.b2_circleShape),Ve(Wm,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(Um,Y.b2_polygonShape,Y.b2_circleShape),Ve(zm,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Km,Y.b2_polygonShape,Y.b2_polygonShape),Ve(Hm,Y.b2_segmentShape,Y.b2_circleShape),Ve($m,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(Zm,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_polygonShape),Th=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Vm(e.friction,o.friction),h.restitution=Ym(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function xo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function oy(t,e,o,n,s){let r=new he;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var _u=new To;function Au(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=oy(o,n,r,i,e.cache);else{e.manifold.copyTo(_u);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Ju=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Mu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function ny(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew wu),sy(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function sy(t,e,o){let n=o.broadPhase,s=new vu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,cy(s),s.dt>0&&ul(n,s),n.locked=!1}var An=new g,ts=new g,ly=new rt,Ru=new at(An,ly);function Lh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;U2(s,r.center,Ru),e.image?t.DrawImageCircle(Ru,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Ru,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var ju=class{constructor(e,o){this.world=e,this.draw=o}};function dy(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Lh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function by(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new ju(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Rh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Rh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=be(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Vu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){by(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Lh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=be(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Yu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Nu(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Wu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function Ou(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function Qu(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function Zu(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function t2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function e2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function o2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function py(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var Fu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function n2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new Fu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function r2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Si;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function c2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Qa(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=lt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function x2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Xu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,hy,r)}function Lu(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function ii(t){if(!uo)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=Lu(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=Lu(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!uo)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Fh(){}function Xh(){}function qh(){}var kg=new g;var I2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Ai({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new I2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new mo;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{_2(e,o)})}function _2(t,e){let o=ai(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function $h(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=B2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=g2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t){let e=t.worldDef;return e||(e=lr()),_i(),{worldId:gi(e)}}var Ja=0;function tm(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=le(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=fo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function nm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function A2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function sm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ci(t){let e=t.jointDef;return e||(e=new mo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function rm(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function im(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var yA=0,fA=1,xA=2;export{Oh as AddSpriteToWorld,bh as B2_ID_EQUALS,dh as B2_IS_NON_NULL,lh as B2_IS_NULL,x as B2_NULL_INDEX,_2 as BodyToSprite,zh as ClearWorldSprites,B2 as CreateBoxPolygon,Ai as CreateCapsule,em as CreateChain,g2 as CreateCircle,im as CreateDistanceJoint,lm as CreateMotorJoint,dm as CreateMouseJoint,om as CreateNGonPolygon,sm as CreatePhysicsEditorShape,va as CreatePolygon,nm as CreatePolygonFromEarcut,A2 as CreatePolygonFromVertices,cm as CreatePrismaticJoint,Ci as CreateRevoluteJoint,rm as CreateWeldJoint,am as CreateWheelJoint,Zh as CreateWorld,xA as DYNAMIC,Kh as GetBodyFromSprite,Yh as GetWorldScale,fA as KINEMATIC,Ca as Ragdoll,Uh as RemoveSpriteFromWorld,wa as RotFromRad,yA as STATIC,Vh as SetWorldScale,Aa as Skeletons,$h as SpriteToBox,Qh as SpriteToCircle,Hh as UpdateWorldSprites,tm as WorldStep,xt as b2AABB,Le as b2AABB_Center,Jo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,D2 as b2AbsFloat,T2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Gp as b2Body_ApplyAngularImpulse,Dp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,kp as b2Body_ApplyLinearImpulse,Tp as b2Body_ApplyLinearImpulseToCenter,Np as b2Body_ApplyMassFromShapes,Pp as b2Body_ApplyTorque,_p as b2Body_ComputeAABB,su as b2Body_Disable,ru as b2Body_Enable,du as b2Body_EnableHitEvents,nu as b2Body_EnableSleep,zp as b2Body_GetAngularDamping,vp as b2Body_GetAngularVelocity,Ip as b2Body_GetContactCapacity,Sp as b2Body_GetContactData,Hp as b2Body_GetGravityScale,pu as b2Body_GetJointCount,uu as b2Body_GetJoints,Op as b2Body_GetLinearDamping,wp as b2Body_GetLinearVelocity,Xp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,Ap as b2Body_GetLocalVector,jp as b2Body_GetMass,Yp as b2Body_GetMassData,gp as b2Body_GetPosition,Us as b2Body_GetRotation,Fp as b2Body_GetRotationalInertia,bu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,ou as b2Body_GetSleepThreshold,ai as b2Body_GetTransform,Rp as b2Body_GetType,Ep as b2Body_GetUserData,qp as b2Body_GetWorldCenterOfMass,Bp as b2Body_GetWorldPoint,Cp as b2Body_GetWorldVector,$p as b2Body_IsAwake,lu as b2Body_IsBullet,Zp as b2Body_IsEnabled,au as b2Body_IsFixedRotation,tu as b2Body_IsSleepEnabled,Uu as b2Body_IsValid,Up as b2Body_SetAngularDamping,Mp as b2Body_SetAngularVelocity,Qp as b2Body_SetAwake,cu as b2Body_SetBullet,iu as b2Body_SetFixedRotation,Kp as b2Body_SetGravityScale,Wp as b2Body_SetLinearDamping,Jp as b2Body_SetLinearVelocity,Vp as b2Body_SetMassData,eu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,Lp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,Ku as b2Chain_IsValid,Rc as b2Chain_SetFriction,Lc as b2Chain_SetRestitution,ce as b2Circle,L2 as b2Clamp,ht as b2ClampFloat,G2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,yi as b2CollideChainSegmentAndCapsule,mi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,li as b2CollideCircles,pi as b2CollidePolygonAndCapsule,di as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,bi as b2CollideSegmentAndCapsule,ui as b2CollideSegmentAndCircle,hi as b2CollideSegmentAndPolygon,X2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Ao as b2CreateBody,qn as b2CreateCapsuleShape,Ha as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,fo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,za as b2CreateSegmentShape,nh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,gi as b2CreateWorld,_i as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Hb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,$b as b2DefaultMotorJointDef,Qb as b2DefaultMouseJointDef,Zb as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,tp as b2DefaultWeldJointDef,ep as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,$a as b2DestroyChain,ni as b2DestroyJoint,Ka as b2DestroyShape,qu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,he as b2DistanceInput,Ho as b2DistanceJointDef,Il as b2DistanceJoint_EnableLimit,Pl as b2DistanceJoint_EnableMotor,Cl as b2DistanceJoint_EnableSpring,Al as b2DistanceJoint_GetCurrentLength,xl as b2DistanceJoint_GetLength,Bl as b2DistanceJoint_GetMaxLength,El as b2DistanceJoint_GetMaxMotorForce,gl as b2DistanceJoint_GetMinLength,Rl as b2DistanceJoint_GetMotorForce,Gl as b2DistanceJoint_GetMotorSpeed,Dl as b2DistanceJoint_GetSpringDampingRatio,Ml as b2DistanceJoint_GetSpringHertz,Sl as b2DistanceJoint_IsLimitEnabled,kl as b2DistanceJoint_IsMotorEnabled,wl as b2DistanceJoint_IsSpringEnabled,fl as b2DistanceJoint_SetLength,_l as b2DistanceJoint_SetLengthRange,Ll as b2DistanceJoint_SetMaxMotorForce,Tl as b2DistanceJoint_SetMotorSpeed,Jl as b2DistanceJoint_SetSpringDampingRatio,vl as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,ue as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Qc as b2DynamicTree_GetAreaRatio,nl as b2DynamicTree_GetByteCount,$c as b2DynamicTree_GetHeight,tl as b2DynamicTree_GetMaxBalance,Hc as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,el as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,ol as b2DynamicTree_ShiftOrigin,Zc as b2DynamicTree_Validate,ho as b2Filter,oh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,rh as b2GetMilliseconds,ih as b2GetMillisecondsAndReset,we as b2GetSweepTransform,sh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,j2 as b2IntegrateRotation,O2 as b2InvMulRot,ki as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,wi as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,np as b2Joint_GetBodyA,sp as b2Joint_GetBodyB,cp as b2Joint_GetCollideConnected,bp as b2Joint_GetConstraintForce,pp as b2Joint_GetConstraintTorque,rp as b2Joint_GetLocalAnchorA,ip as b2Joint_GetLocalAnchorB,op as b2Joint_GetType,dp as b2Joint_GetUserData,Hu as b2Joint_IsValid,ap as b2Joint_SetCollideConnected,lp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,de as b2LeftPerp,Yt as b2Length,pe as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Di as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Mi as b2Max,M2 as b2MaxFloat,k2 as b2MaxInt,Ji as b2Min,J2 as b2MinFloat,P2 as b2MinInt,$o as b2MotorJointDef,bb as b2MotorJoint_GetAngularOffset,fb as b2MotorJoint_GetCorrectionFactor,lb as b2MotorJoint_GetLinearOffset,ub as b2MotorJoint_GetMaxForce,mb as b2MotorJoint_GetMaxTorque,db as b2MotorJoint_SetAngularOffset,yb as b2MotorJoint_SetCorrectionFactor,cb as b2MotorJoint_SetLinearOffset,pb as b2MotorJoint_SetMaxForce,hb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,Db as b2MouseJoint_GetMaxForce,Jb as b2MouseJoint_GetSpringDampingRatio,wb as b2MouseJoint_GetSpringHertz,Ab as b2MouseJoint_GetTarget,Mb as b2MouseJoint_SetMaxForce,vb as b2MouseJoint_SetSpringDampingRatio,Cb as b2MouseJoint_SetSpringHertz,Bb as b2MouseJoint_SetTarget,R2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,z2 as b2MulTransforms,Pi as b2NLerp,Ht as b2Neg,lt as b2Normalize,H2 as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,Kl as b2PrismaticJoint_EnableLimit,td as b2PrismaticJoint_EnableMotor,Yl as b2PrismaticJoint_EnableSpring,$l as b2PrismaticJoint_GetLowerLimit,id as b2PrismaticJoint_GetMaxMotorForce,sd as b2PrismaticJoint_GetMotorForce,nd as b2PrismaticJoint_GetMotorSpeed,zl as b2PrismaticJoint_GetSpringDampingRatio,Ol as b2PrismaticJoint_GetSpringHertz,Ql as b2PrismaticJoint_GetUpperLimit,Hl as b2PrismaticJoint_IsLimitEnabled,ed as b2PrismaticJoint_IsMotorEnabled,Nl as b2PrismaticJoint_IsSpringEnabled,Zl as b2PrismaticJoint_SetLimits,rd as b2PrismaticJoint_SetMaxMotorForce,od as b2PrismaticJoint_SetMotorSpeed,Ul as b2PrismaticJoint_SetSpringDampingRatio,Wl as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,mo as b2RevoluteJointDef,Sd as b2RevoluteJoint_EnableLimit,Cd as b2RevoluteJoint_EnableMotor,ud as b2RevoluteJoint_EnableSpring,Id as b2RevoluteJoint_GetAngle,gd as b2RevoluteJoint_GetLowerLimit,Pd as b2RevoluteJoint_GetMaxMotorTorque,Jd as b2RevoluteJoint_GetMotorSpeed,Md as b2RevoluteJoint_GetMotorTorque,xd as b2RevoluteJoint_GetSpringDampingRatio,yd as b2RevoluteJoint_GetSpringHertz,Bd as b2RevoluteJoint_GetUpperLimit,_d as b2RevoluteJoint_IsLimitEnabled,wd as b2RevoluteJoint_IsMotorEnabled,hd as b2RevoluteJoint_IsSpringEnabled,Ad as b2RevoluteJoint_SetLimits,Dd as b2RevoluteJoint_SetMaxMotorTorque,vd as b2RevoluteJoint_SetMotorSpeed,fd as b2RevoluteJoint_SetSpringDampingRatio,md as b2RevoluteJoint_SetSpringHertz,be as b2RightPerp,rt as b2Rot,q2 as b2Rot_GetAngle,V2 as b2Rot_GetXAxis,Y2 as b2Rot_GetYAxis,K2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,eh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,lo as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Ic as b2Shape_AreContactEventsEnabled,Bc as b2Shape_AreHitEventsEnabled,_c as b2Shape_ArePreSolveEventsEnabled,fc as b2Shape_AreSensorEventsEnabled,xc as b2Shape_EnableContactEvents,gc as b2Shape_EnableHitEvents,Sc as b2Shape_EnablePreSolveEvents,yc as b2Shape_EnableSensorEvents,Fc as b2Shape_GetAABB,oc as b2Shape_GetBody,Jc as b2Shape_GetCapsule,vc as b2Shape_GetChainSegment,Cc as b2Shape_GetCircle,Xc as b2Shape_GetClosestPoint,Ec as b2Shape_GetContactCapacity,jc as b2Shape_GetContactData,lc as b2Shape_GetDensity,hc as b2Shape_GetFilter,bc as b2Shape_GetFriction,Gc as b2Shape_GetParentChain,Mc as b2Shape_GetPolygon,uc as b2Shape_GetRestitution,wc as b2Shape_GetSegment,Ac as b2Shape_GetType,sc as b2Shape_GetUserData,rc as b2Shape_IsSensor,zu as b2Shape_IsValid,ac as b2Shape_RayCast,Pc as b2Shape_SetCapsule,Dc as b2Shape_SetCircle,cc as b2Shape_SetDensity,mc as b2Shape_SetFilter,dc as b2Shape_SetFriction,Tc as b2Shape_SetPolygon,pc as b2Shape_SetRestitution,kc as b2Shape_SetSegment,nc as b2Shape_SetUserData,ic as b2Shape_TestPoint,Mn as b2Simplex,ah as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,bo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,vo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Yb as b2WeldJoint_GetAngularDampingRatio,qb as b2WeldJoint_GetAngularHertz,Fb as b2WeldJoint_GetLinearDampingRatio,Eb as b2WeldJoint_GetLinearHertz,Vb as b2WeldJoint_SetAngularDampingRatio,Xb as b2WeldJoint_SetAngularHertz,jb as b2WeldJoint_SetLinearDampingRatio,Lb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Nd as b2WheelJoint_EnableLimit,Kd as b2WheelJoint_EnableMotor,jd as b2WheelJoint_EnableSpring,Od as b2WheelJoint_GetLowerLimit,eb as b2WheelJoint_GetMaxMotorTorque,Qd as b2WheelJoint_GetMotorSpeed,Zd as b2WheelJoint_GetMotorTorque,Yd as b2WheelJoint_GetSpringDampingRatio,qd as b2WheelJoint_GetSpringHertz,Ud as b2WheelJoint_GetUpperLimit,Wd as b2WheelJoint_IsLimitEnabled,Hd as b2WheelJoint_IsMotorEnabled,Fd as b2WheelJoint_IsSpringEnabled,zd as b2WheelJoint_SetLimits,tb as b2WheelJoint_SetMaxMotorTorque,$d as b2WheelJoint_SetMotorSpeed,Vd as b2WheelJoint_SetSpringDampingRatio,Xd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,co as b2WorldId,p2 as b2World_CastCapsule,b2 as b2World_CastCircle,u2 as b2World_CastPolygon,c2 as b2World_CastRay,l2 as b2World_CastRayClosest,Vu as b2World_Draw,qh as b2World_DumpMemoryStats,Zu as b2World_EnableContinuous,$u as b2World_EnableSleeping,Qu as b2World_EnableWarmStarting,x2 as b2World_Explode,Yu as b2World_GetBodyEvents,Wu as b2World_GetContactEvents,Xh as b2World_GetCounters,f2 as b2World_GetGravity,Fh as b2World_GetProfile,Nu as b2World_GetSensorEvents,Ou as b2World_IsValid,n2 as b2World_OverlapAABB,i2 as b2World_OverlapCapsule,r2 as b2World_OverlapCircle,a2 as b2World_OverlapPolygon,o2 as b2World_SetContactTuning,m2 as b2World_SetCustomFilterCallback,y2 as b2World_SetGravity,e2 as b2World_SetHitEventThreshold,h2 as b2World_SetPreSolveCallback,t2 as b2World_SetRestitutionThreshold,Bi as b2World_Step,ch as b2Yield,Nh as mpx,Wh as pxm,or as pxmVec2}; +function Ye(t){let e=Yt(t);if(ee?t:e}function D2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function P2(t,e){return te?t:e}function T2(t){return t<0?-t:t}function G2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function de(t){return new g(-t.y,t.x)}function be(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function R2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function vi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function Ji(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Mi(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function L2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function pe(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function ue(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Di(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function E2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function wi(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function F2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function X2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function q2(t){return Math.atan2(t.s,t.c)}function V2(t){return new g(t.c,t.s)}function Y2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function N2(t,e){return t.c*e.c-t.s*e.s}function W2(t,e){return t.s*e.c+t.c*e.s}function O2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function vo(t){return t<-wo?t+2*wo:t>wo?t-2*wo:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function U2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function z2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function ki(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function Jo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function K2(t){return t&&ae(t.s)&&ae(t.c)&&wi(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function lt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function H2(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Q2=1,x=-1;function Ta(t){Q2=t}function Ga(){return Q2}function Ra(t){}function La(){return new Ti(3,1,0)}var We=1,De=1e5*We,te=2,It=.005*We;var Z2=.25*Math.PI,Qt=4*It,vn=.1*We,th=.5;function eh(){}function oh(){}function nh(){}function sh(){}function rh(){}function ih(t){}function ah(t){}function ch(){}var co=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function lh(t){return t.index1===0}function dh(t){return t.index1!==0}function bh(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function pm(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?de(e):be(e);default:return new g(0,0)}}function mm(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function hh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function mh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function yh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=pm(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=yo(o,Ht(y)),h=o.points[u],m=yo(i,y),f=i.points[m];let v=J(h,f);y=lt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:mh(p);break;case 3:yh(p);break;default:}if(p.count===3)return e;y=mm(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;hh(B,A,p);let w=lt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function xm(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new bo,Object.assign(i.sweepA,o),i.sweepB=new bo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=lt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=lt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=lt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Im(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=yo(t.proxyA,s),c=yo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=yo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=yo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function uh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new he;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=uh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=lt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=ue(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=lt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new lo;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new lo;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new lo;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function Ih(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation||n.isSensor)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(ue(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function fo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function za(t,e,o){return ue(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function Sh(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&xo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ka(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);Sh(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function Ha(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&xo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function mc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function fc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function xc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Ic(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function Sc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function _c(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Bc(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Ac(t){let e=O(t.world0);return Bt(e,t).type}function Cc(t){let e=O(t.world0);return Bt(e,t).circle}function wc(t){let e=O(t.world0);return Bt(e,t).segment}function vc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Jc(t){let e=O(t.world0);return Bt(e,t).capsule}function Mc(t){let e=O(t.world0);return Bt(e,t).polygon}function Dc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Gc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Rc(t,e){let o=ft(t.world0);if(o===null)return;let n=Ih(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Fc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function Xc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new he;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new ho,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,dt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=dt>0?1/dt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Nc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,dt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*dt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(dt*ut-Et*Ge)}for(let ot=0;otdt?dt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var vm=1024;function Bh(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&sl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=lt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Mm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(vm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:gh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:gh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Mm(t,o),o}function Ch(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=il(o.bodyCount),i.contacts=al(o.contactCount),i.joints=cl(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(Io(C.bodySet,y.edges[0].bodyId),Io(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(Io(_.bodySet,y.edges[0].bodyId),Io(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function rl(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function Pm(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,Jo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Tm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Dm(s,r,e):n===yn.b2_stageIntegratePositions&&Pm(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Rm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new bl;N.context=e,N.workerIndex=0,Gm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&Em(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&jm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(_h(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function fl(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function xl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function _l(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Bl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function Al(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=le(o,e.bodyIdA),s=le(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function Cl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function wl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Ml(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function Dl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Pl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Tl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function Rl(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function Ll(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function El(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function jl(t,e){let o=e.distanceJoint,n=le(t,e.bodyIdA),s=le(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=lt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function Fl(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=lt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Xl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=lt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function ql(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=lt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Vl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=lt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Yl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Nl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function $l(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function Zl(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function td(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function ed(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function od(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function sd(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function rd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function id(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ad(t,e){let o=e.bodyIdA,n=le(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=de(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function cd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function dd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=de(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function bd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=de(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function pd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function ud(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function hd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function Id(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=le(e,o.bodyIdA),s=le(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=vo(r),r}function Sd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function _d(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function gd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function Ad(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function Cd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function wd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function vd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Md(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function Dd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Pd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function kd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Td(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Gd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=vo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Rd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function Ld(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=vo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Ed(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function jd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function Fd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Xd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function Od(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function zd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function Kd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Hd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function Zd(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function tb(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function eb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function ob(t,e){let o=e.wheelJoint,n=o.axisA,s=de(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function nb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=de(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function rb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=de(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function ib(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=de(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function ab(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function cb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function lb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-wo,wo)}function bb(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function xb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function Ib(t,e){return t.inv_h*e.motorJoint.angularImpulse}function Sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=vo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function _b(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function gb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=vo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),pe(a.linearImpulse)>w*w&&(a.linearImpulse=lt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Bb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function Ab(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function Cb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Pb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function kb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Tb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Gb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Rb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,lt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function Lb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Eb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Nb(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Wb(t,e){return t.inv_h*e.weldJoint.angularImpulse}function Ob(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Ub(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function zb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Hb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function $b(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function Qb(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function Zb(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new mo;return t.drawSize=.25,t}function tp(){return new tn}function ep(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var Kb=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function Kn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new zn,new zn],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(rl(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p,!0),Lt(t),new Kb(p,h)}function Hn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&xo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=Kn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=lt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=lt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,e.islandId!==x&&Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function op(t){let e=O(t.world0);return Je(e,t).type}function np(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function sp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function rp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function ip(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function ap(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){up(t,i,e);return}let a=null;if(i!==x){a=go(t,i);let d=a.parentIsland;for(;d!==x;){let p=go(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=go(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=go(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?up(t,i,e):up(t,c,e)}function ri(t,e){let o=e.islandId,n=go(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function hp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,Bo(t,e)}function Ys(t,e,o){let n=_t(t,e.edges[0].bodyId),s=_t(t,e.edges[1].bodyId);n.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet?qe(t,s.setIndex):s.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet&&qe(t,n.setIndex);let r=n.islandId,i=s.islandId;if(r===i){hp(t,r,e);return}let c=null;if(r!==x)for(c=go(t,r);c.parentIsland!==x;){let l=go(t,c.parentIsland);l.parentIsland!==x&&(c.parentIsland=l.parentIsland),r=c.parentIsland,c=l}let a=null;if(i!==x)for(a=go(t,i);a.parentIsland!==x;){let l=go(t,a.parentIsland);l.parentIsland!==x&&(a.parentIsland=l.parentIsland),i=a.parentIsland,a=l}c!==a&&c!==null&&a!==null&&(a.parentIsland=r),c!==null?hp(t,r,e):hp(t,i,e),o&&Un(t)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function qm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,Bo(t,o)}function Un(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(qm(t,c),si(t,i))}ii(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;Bo(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}Bo(t,f)}}function Bo(t,e){if(!uo)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function le(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function yp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function fp(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&Bo(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function xp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,xo(t,i,o)}Lt(t)}function Ao(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&yp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}xp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}fp(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function Ip(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function Sp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function _p(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=le(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=Za(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function gp(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ai(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Bp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function Ap(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,Jo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function wp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function vp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Jp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;pe(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Mp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function Dp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Pp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Gp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Rp(t){let e=O(t.world0);return Z(e,t).type}function Lp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}xp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),yp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?_o(o,c,i,u):u.setIndex===M.b2_awakeSet&&(_o(o,i,c,u),_o(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),fp(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?_o(o,i,c,u):(_o(o,i,c,u),_o(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l,!1))}Un(o)}cn(o,n),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Ep(t){let e=O(t.world0);return Z(e,t).userData}function jp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function Fp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Vp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Yp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Np(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Wp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function Op(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function $p(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function Qp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function tu(t){let e=O(t.world0);return Z(e,t).enableSleep}function eu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function ou(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function nu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function su(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;xp(e,o,!0),fp(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];_o(e,i,p,d)}ii(e),Lt(e)}function ru(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let b=e.shapeArray[l];l=b.nextShapeId,Vn(b,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&yp(e,s,o);let d=!1,p=o.headJointKey;for(;p!==x;){let b=p>>1,u=p&1,h=e.jointArray[b];p=h.edges[u].nextKey;let m=e.bodyArray[h.edges[0].bodyId],f=e.bodyArray[h.edges[1].bodyId];if(m.setIndex===M.b2_disabledSet||f.setIndex===M.b2_disabledSet)continue;let y;m.setIndex===M.b2_staticSet&&f.setIndex===M.b2_staticSet?y=M.b2_staticSet:m.setIndex===M.b2_staticSet?y=f.setIndex:y=m.setIndex;let I=e.solverSetArray[y];_o(e,I,n,h),y!==M.b2_staticSet&&Ys(e,h,d)}Un(e),Lt(e)}function iu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function au(t){let e=O(t.world0);return Z(e,t).fixedRotation}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function lu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function du(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function bu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function pu(t){let e=O(t.world0);return Z(e,t).jointCount}function uu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Co=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function il(t){let e=new Es(t);return t>0?(e.data=po(t,()=>new Hs),e):(e.data=null,e)}function al(t){let e=new ln(t);return t>0?(e.data=po(t,()=>new Qn),e):(e.data=null,e)}function cl(t){let e=new dn(t);return t>0?(e.data=po(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=po(Co,()=>new Hs),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=po(Co,()=>new Pt),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=po(Co,()=>new Qn),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=po(Co,()=>new Ws),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=po(Co,()=>new Os),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ci(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),hu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function Su(t,e,o){let n=J(e,t),s=lt(n),r=be(s),i=new ge;return i.vertices=[t,e],i.centroid=$t(t,e,.5),i.normals=[r,Ht(r)],i.count=2,i.radius=o,i}function li(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function di(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;vi(e.p,1,K(e.q,r),hu.p),hu.q=e.q,Uo(hu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=ue(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let dt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let dt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let dt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);dt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);dt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,dt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+dt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;vi(D,.5*(R-X-P),b,pt),vi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function kh(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),mu=new g,yu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;mu.x=e.p.x+(e.q.c*r-e.q.s*i),mu.y=e.p.y+(e.q.s*r+e.q.c*i),yu.p=mu,yu.q=e.q,Uo(yu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else Ph(kt,Ut,a,p,h,s)}else Ph(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function yi(t,e,o,n,s,r){let i=Su(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function fu(t,e,o,n,s,r,i,c,a,l){let d=de(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function xu(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var Iu=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=lt(J(l,a)),p=new Iu;p.edge1=d.clone();let b=.01,u=lt(J(a,t.ghost1));p.normal0=be(u),p.convex1=z(u,d)>=b;let h=lt(J(t.ghost2,l));p.normal2=be(h),p.convex2=z(d,h)>=b;let m=be(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=lt(J(et,W)),ot=xu(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=xu(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new gu)),Th=!1;function Nm(t,e,o,n,s,r){return li(t.circle,e,o.circle,n,r)}function Wm(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function Um(t,e,o,n,s,r){return di(t.polygon,e,o.circle,n,r)}function zm(t,e,o,n,s,r){return pi(t.polygon,e,o.capsule,n,r)}function Km(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function Hm(t,e,o,n,s,r){return ui(t.segment,e,o.circle,n,r)}function $m(t,e,o,n,s,r){return bi(t.segment,e,o.capsule,n,r)}function Qm(t,e,o,n,s,r){return hi(t.segment,e,o.polygon,n,r)}function Zm(t,e,o,n,s,r){return mi(t.chainSegment,e,o.circle,n,r)}function ty(t,e,o,n,s,r){return yi(t.chainSegment,e,o.capsule,n,s,r)}function ey(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Bu(){Th===!1&&(Ve(Nm,Y.b2_circleShape,Y.b2_circleShape),Ve(Wm,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(Um,Y.b2_polygonShape,Y.b2_circleShape),Ve(zm,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Km,Y.b2_polygonShape,Y.b2_polygonShape),Ve(Hm,Y.b2_segmentShape,Y.b2_circleShape),Ve($m,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(Zm,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_polygonShape),Th=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Vm(e.friction,o.friction),h.restitution=Ym(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function xo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function oy(t,e,o,n,s){let r=new he;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var _u=new To;function Au(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=oy(o,n,r,i,e.cache);else{e.manifold.copyTo(_u);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Ju=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Mu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function ny(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew wu),sy(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function sy(t,e,o){let n=o.broadPhase,s=new vu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,cy(s),s.dt>0&&ul(n,s),n.locked=!1}var An=new g,ts=new g,ly=new rt,Ru=new at(An,ly);function Lh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;U2(s,r.center,Ru),e.image?t.DrawImageCircle(Ru,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Ru,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var ju=class{constructor(e,o){this.world=e,this.draw=o}};function dy(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Lh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function by(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new ju(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Rh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Rh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=be(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Vu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){by(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Lh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=be(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Yu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Nu(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Wu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function Ou(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function Qu(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function Zu(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function t2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function e2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function o2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function py(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var Fu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function n2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new Fu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function r2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Si;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function c2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Qa(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=lt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function x2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Xu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,hy,r)}function Lu(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function ii(t){if(!uo)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=Lu(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=Lu(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!uo)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Fh(){}function Xh(){}function qh(){}var Tg=new g;var I2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Ai({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new I2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new mo;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{_2(e,o)})}function _2(t,e){let o=ai(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function $h(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=B2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=g2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t){let e=t.worldDef;return e||(e=lr()),_i(),{worldId:gi(e)}}var Ja=0;function tm(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=le(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=fo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function nm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function A2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function sm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ci(t){let e=t.jointDef;return e||(e=new mo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function rm(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function im(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var fA=0,xA=1,IA=2;export{Oh as AddSpriteToWorld,bh as B2_ID_EQUALS,dh as B2_IS_NON_NULL,lh as B2_IS_NULL,x as B2_NULL_INDEX,_2 as BodyToSprite,zh as ClearWorldSprites,B2 as CreateBoxPolygon,Ai as CreateCapsule,em as CreateChain,g2 as CreateCircle,im as CreateDistanceJoint,lm as CreateMotorJoint,dm as CreateMouseJoint,om as CreateNGonPolygon,sm as CreatePhysicsEditorShape,va as CreatePolygon,nm as CreatePolygonFromEarcut,A2 as CreatePolygonFromVertices,cm as CreatePrismaticJoint,Ci as CreateRevoluteJoint,rm as CreateWeldJoint,am as CreateWheelJoint,Zh as CreateWorld,IA as DYNAMIC,Kh as GetBodyFromSprite,Yh as GetWorldScale,xA as KINEMATIC,Ca as Ragdoll,Uh as RemoveSpriteFromWorld,wa as RotFromRad,fA as STATIC,Vh as SetWorldScale,Aa as Skeletons,$h as SpriteToBox,Qh as SpriteToCircle,Hh as UpdateWorldSprites,tm as WorldStep,xt as b2AABB,Le as b2AABB_Center,Jo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,D2 as b2AbsFloat,T2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Gp as b2Body_ApplyAngularImpulse,Dp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,kp as b2Body_ApplyLinearImpulse,Tp as b2Body_ApplyLinearImpulseToCenter,Np as b2Body_ApplyMassFromShapes,Pp as b2Body_ApplyTorque,_p as b2Body_ComputeAABB,su as b2Body_Disable,ru as b2Body_Enable,du as b2Body_EnableHitEvents,nu as b2Body_EnableSleep,zp as b2Body_GetAngularDamping,vp as b2Body_GetAngularVelocity,Ip as b2Body_GetContactCapacity,Sp as b2Body_GetContactData,Hp as b2Body_GetGravityScale,pu as b2Body_GetJointCount,uu as b2Body_GetJoints,Op as b2Body_GetLinearDamping,wp as b2Body_GetLinearVelocity,Xp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,Ap as b2Body_GetLocalVector,jp as b2Body_GetMass,Yp as b2Body_GetMassData,gp as b2Body_GetPosition,Us as b2Body_GetRotation,Fp as b2Body_GetRotationalInertia,bu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,ou as b2Body_GetSleepThreshold,ai as b2Body_GetTransform,Rp as b2Body_GetType,Ep as b2Body_GetUserData,qp as b2Body_GetWorldCenterOfMass,Bp as b2Body_GetWorldPoint,Cp as b2Body_GetWorldVector,$p as b2Body_IsAwake,lu as b2Body_IsBullet,Zp as b2Body_IsEnabled,au as b2Body_IsFixedRotation,tu as b2Body_IsSleepEnabled,Uu as b2Body_IsValid,Up as b2Body_SetAngularDamping,Mp as b2Body_SetAngularVelocity,Qp as b2Body_SetAwake,cu as b2Body_SetBullet,iu as b2Body_SetFixedRotation,Kp as b2Body_SetGravityScale,Wp as b2Body_SetLinearDamping,Jp as b2Body_SetLinearVelocity,Vp as b2Body_SetMassData,eu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,Lp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,Ku as b2Chain_IsValid,Rc as b2Chain_SetFriction,Lc as b2Chain_SetRestitution,ce as b2Circle,L2 as b2Clamp,ht as b2ClampFloat,G2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,yi as b2CollideChainSegmentAndCapsule,mi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,li as b2CollideCircles,pi as b2CollidePolygonAndCapsule,di as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,bi as b2CollideSegmentAndCapsule,ui as b2CollideSegmentAndCircle,hi as b2CollideSegmentAndPolygon,X2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Ao as b2CreateBody,qn as b2CreateCapsuleShape,Ha as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,fo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,za as b2CreateSegmentShape,nh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,gi as b2CreateWorld,_i as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Hb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,$b as b2DefaultMotorJointDef,Qb as b2DefaultMouseJointDef,Zb as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,tp as b2DefaultWeldJointDef,ep as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,$a as b2DestroyChain,ni as b2DestroyJoint,Ka as b2DestroyShape,qu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,he as b2DistanceInput,Ho as b2DistanceJointDef,Il as b2DistanceJoint_EnableLimit,Pl as b2DistanceJoint_EnableMotor,Cl as b2DistanceJoint_EnableSpring,Al as b2DistanceJoint_GetCurrentLength,xl as b2DistanceJoint_GetLength,Bl as b2DistanceJoint_GetMaxLength,El as b2DistanceJoint_GetMaxMotorForce,gl as b2DistanceJoint_GetMinLength,Rl as b2DistanceJoint_GetMotorForce,Gl as b2DistanceJoint_GetMotorSpeed,Dl as b2DistanceJoint_GetSpringDampingRatio,Ml as b2DistanceJoint_GetSpringHertz,Sl as b2DistanceJoint_IsLimitEnabled,kl as b2DistanceJoint_IsMotorEnabled,wl as b2DistanceJoint_IsSpringEnabled,fl as b2DistanceJoint_SetLength,_l as b2DistanceJoint_SetLengthRange,Ll as b2DistanceJoint_SetMaxMotorForce,Tl as b2DistanceJoint_SetMotorSpeed,Jl as b2DistanceJoint_SetSpringDampingRatio,vl as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,ue as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Qc as b2DynamicTree_GetAreaRatio,nl as b2DynamicTree_GetByteCount,$c as b2DynamicTree_GetHeight,tl as b2DynamicTree_GetMaxBalance,Hc as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,el as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,ol as b2DynamicTree_ShiftOrigin,Zc as b2DynamicTree_Validate,ho as b2Filter,oh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,rh as b2GetMilliseconds,ih as b2GetMillisecondsAndReset,we as b2GetSweepTransform,sh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,j2 as b2IntegrateRotation,O2 as b2InvMulRot,ki as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,wi as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,np as b2Joint_GetBodyA,sp as b2Joint_GetBodyB,cp as b2Joint_GetCollideConnected,bp as b2Joint_GetConstraintForce,pp as b2Joint_GetConstraintTorque,rp as b2Joint_GetLocalAnchorA,ip as b2Joint_GetLocalAnchorB,op as b2Joint_GetType,dp as b2Joint_GetUserData,Hu as b2Joint_IsValid,ap as b2Joint_SetCollideConnected,lp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,de as b2LeftPerp,Yt as b2Length,pe as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Di as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Mi as b2Max,M2 as b2MaxFloat,k2 as b2MaxInt,Ji as b2Min,J2 as b2MinFloat,P2 as b2MinInt,$o as b2MotorJointDef,bb as b2MotorJoint_GetAngularOffset,fb as b2MotorJoint_GetCorrectionFactor,lb as b2MotorJoint_GetLinearOffset,ub as b2MotorJoint_GetMaxForce,mb as b2MotorJoint_GetMaxTorque,db as b2MotorJoint_SetAngularOffset,yb as b2MotorJoint_SetCorrectionFactor,cb as b2MotorJoint_SetLinearOffset,pb as b2MotorJoint_SetMaxForce,hb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,Db as b2MouseJoint_GetMaxForce,Jb as b2MouseJoint_GetSpringDampingRatio,wb as b2MouseJoint_GetSpringHertz,Ab as b2MouseJoint_GetTarget,Mb as b2MouseJoint_SetMaxForce,vb as b2MouseJoint_SetSpringDampingRatio,Cb as b2MouseJoint_SetSpringHertz,Bb as b2MouseJoint_SetTarget,R2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,z2 as b2MulTransforms,Pi as b2NLerp,Ht as b2Neg,lt as b2Normalize,H2 as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,Kl as b2PrismaticJoint_EnableLimit,td as b2PrismaticJoint_EnableMotor,Yl as b2PrismaticJoint_EnableSpring,$l as b2PrismaticJoint_GetLowerLimit,id as b2PrismaticJoint_GetMaxMotorForce,sd as b2PrismaticJoint_GetMotorForce,nd as b2PrismaticJoint_GetMotorSpeed,zl as b2PrismaticJoint_GetSpringDampingRatio,Ol as b2PrismaticJoint_GetSpringHertz,Ql as b2PrismaticJoint_GetUpperLimit,Hl as b2PrismaticJoint_IsLimitEnabled,ed as b2PrismaticJoint_IsMotorEnabled,Nl as b2PrismaticJoint_IsSpringEnabled,Zl as b2PrismaticJoint_SetLimits,rd as b2PrismaticJoint_SetMaxMotorForce,od as b2PrismaticJoint_SetMotorSpeed,Ul as b2PrismaticJoint_SetSpringDampingRatio,Wl as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,mo as b2RevoluteJointDef,Sd as b2RevoluteJoint_EnableLimit,Cd as b2RevoluteJoint_EnableMotor,ud as b2RevoluteJoint_EnableSpring,Id as b2RevoluteJoint_GetAngle,gd as b2RevoluteJoint_GetLowerLimit,Pd as b2RevoluteJoint_GetMaxMotorTorque,Jd as b2RevoluteJoint_GetMotorSpeed,Md as b2RevoluteJoint_GetMotorTorque,xd as b2RevoluteJoint_GetSpringDampingRatio,yd as b2RevoluteJoint_GetSpringHertz,Bd as b2RevoluteJoint_GetUpperLimit,_d as b2RevoluteJoint_IsLimitEnabled,wd as b2RevoluteJoint_IsMotorEnabled,hd as b2RevoluteJoint_IsSpringEnabled,Ad as b2RevoluteJoint_SetLimits,Dd as b2RevoluteJoint_SetMaxMotorTorque,vd as b2RevoluteJoint_SetMotorSpeed,fd as b2RevoluteJoint_SetSpringDampingRatio,md as b2RevoluteJoint_SetSpringHertz,be as b2RightPerp,rt as b2Rot,q2 as b2Rot_GetAngle,V2 as b2Rot_GetXAxis,Y2 as b2Rot_GetYAxis,K2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,eh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,lo as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Ic as b2Shape_AreContactEventsEnabled,Bc as b2Shape_AreHitEventsEnabled,_c as b2Shape_ArePreSolveEventsEnabled,fc as b2Shape_AreSensorEventsEnabled,xc as b2Shape_EnableContactEvents,gc as b2Shape_EnableHitEvents,Sc as b2Shape_EnablePreSolveEvents,yc as b2Shape_EnableSensorEvents,Fc as b2Shape_GetAABB,oc as b2Shape_GetBody,Jc as b2Shape_GetCapsule,vc as b2Shape_GetChainSegment,Cc as b2Shape_GetCircle,Xc as b2Shape_GetClosestPoint,Ec as b2Shape_GetContactCapacity,jc as b2Shape_GetContactData,lc as b2Shape_GetDensity,hc as b2Shape_GetFilter,bc as b2Shape_GetFriction,Gc as b2Shape_GetParentChain,Mc as b2Shape_GetPolygon,uc as b2Shape_GetRestitution,wc as b2Shape_GetSegment,Ac as b2Shape_GetType,sc as b2Shape_GetUserData,rc as b2Shape_IsSensor,zu as b2Shape_IsValid,ac as b2Shape_RayCast,Pc as b2Shape_SetCapsule,Dc as b2Shape_SetCircle,cc as b2Shape_SetDensity,mc as b2Shape_SetFilter,dc as b2Shape_SetFriction,Tc as b2Shape_SetPolygon,pc as b2Shape_SetRestitution,kc as b2Shape_SetSegment,nc as b2Shape_SetUserData,ic as b2Shape_TestPoint,Mn as b2Simplex,ah as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,bo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,vo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Yb as b2WeldJoint_GetAngularDampingRatio,qb as b2WeldJoint_GetAngularHertz,Fb as b2WeldJoint_GetLinearDampingRatio,Eb as b2WeldJoint_GetLinearHertz,Vb as b2WeldJoint_SetAngularDampingRatio,Xb as b2WeldJoint_SetAngularHertz,jb as b2WeldJoint_SetLinearDampingRatio,Lb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Nd as b2WheelJoint_EnableLimit,Kd as b2WheelJoint_EnableMotor,jd as b2WheelJoint_EnableSpring,Od as b2WheelJoint_GetLowerLimit,eb as b2WheelJoint_GetMaxMotorTorque,Qd as b2WheelJoint_GetMotorSpeed,Zd as b2WheelJoint_GetMotorTorque,Yd as b2WheelJoint_GetSpringDampingRatio,qd as b2WheelJoint_GetSpringHertz,Ud as b2WheelJoint_GetUpperLimit,Wd as b2WheelJoint_IsLimitEnabled,Hd as b2WheelJoint_IsMotorEnabled,Fd as b2WheelJoint_IsSpringEnabled,zd as b2WheelJoint_SetLimits,tb as b2WheelJoint_SetMaxMotorTorque,$d as b2WheelJoint_SetMotorSpeed,Vd as b2WheelJoint_SetSpringDampingRatio,Xd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,co as b2WorldId,p2 as b2World_CastCapsule,b2 as b2World_CastCircle,u2 as b2World_CastPolygon,c2 as b2World_CastRay,l2 as b2World_CastRayClosest,Vu as b2World_Draw,qh as b2World_DumpMemoryStats,Zu as b2World_EnableContinuous,$u as b2World_EnableSleeping,Qu as b2World_EnableWarmStarting,x2 as b2World_Explode,Yu as b2World_GetBodyEvents,Wu as b2World_GetContactEvents,Xh as b2World_GetCounters,f2 as b2World_GetGravity,Fh as b2World_GetProfile,Nu as b2World_GetSensorEvents,Ou as b2World_IsValid,n2 as b2World_OverlapAABB,i2 as b2World_OverlapCapsule,r2 as b2World_OverlapCircle,a2 as b2World_OverlapPolygon,o2 as b2World_SetContactTuning,m2 as b2World_SetCustomFilterCallback,y2 as b2World_SetGravity,e2 as b2World_SetHitEventThreshold,h2 as b2World_SetPreSolveCallback,t2 as b2World_SetRestitutionThreshold,Bi as b2World_Step,ch as b2Yield,Nh as mpx,Wh as pxm,or as pxmVec2}; diff --git a/src/include/world_h.js b/src/include/world_h.js index 1f0d72b..7b7d162 100644 --- a/src/include/world_h.js +++ b/src/include/world_h.js @@ -20,6 +20,7 @@ export { b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback, b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold, b2World_IsValid, b2Joint_IsValid, + b2World_IsSleepingEnabled, b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold, b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled, b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts, From ce13e81543db15115f2e749d26606ec4e9198b4c Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:18:18 -0800 Subject: [PATCH 09/14] CreatePolygonFromVertices: return bodyId. fixes #15 --- src/physics.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/physics.js b/src/physics.js index 413f20a..2c5096a 100644 --- a/src/physics.js +++ b/src/physics.js @@ -1066,8 +1066,11 @@ export function CreatePolygonFromVertices (data) b2CreatePolygonShape(body.bodyId, shapeDef, nGon); } }); + + return body; } + /** * Creates a polygon from PhysicsEditor XML data and attaches it to a body. * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow. @@ -1181,6 +1184,7 @@ export function CreatePhysicsEditorShape (data) }); } + /** * @typedef {Object} RevoluteJointConfig * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist. From 0c4e0cd635375b399a58bd78438b31296c6504d1 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:18:34 -0800 Subject: [PATCH 10/14] fix lint errors --- src/joint_c.js | 1 + src/shape_c.js | 2 ++ src/world_c.js | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/src/joint_c.js b/src/joint_c.js index 262a1c6..2a26b26 100644 --- a/src/joint_c.js +++ b/src/joint_c.js @@ -1068,6 +1068,7 @@ export function b2DestroyJoint(jointId) export function b2Joint_GetWorld(jointId) { const world = b2GetWorld(jointId.world0); + return new b2WorldId(jointId.world0 + 1, world.revision); } diff --git a/src/shape_c.js b/src/shape_c.js index 9f0bcb0..8b192dd 100644 --- a/src/shape_c.js +++ b/src/shape_c.js @@ -1788,6 +1788,7 @@ export function b2Shape_GetParentChain(shapeId) export function b2Chain_GetWorld(chainId) { const world = b2GetWorld(chainId.world0); + return new b2WorldId(chainId.world0 + 1, world.revision); } @@ -1802,6 +1803,7 @@ export function b2Chain_GetSegmentCount(chainId) { const world = b2GetWorldLocked(chainId.world0); const chainShape = b2GetChainShape(world, chainId); + return chainShape.count; } diff --git a/src/world_c.js b/src/world_c.js index 991545b..58feb92 100644 --- a/src/world_c.js +++ b/src/world_c.js @@ -2093,6 +2093,7 @@ export function b2World_EnableSleeping(worldId, flag) export function b2World_IsSleepingEnabled(worldId) { const world = b2GetWorldFromId(worldId); + return world.enableSleep; } @@ -2106,6 +2107,7 @@ export function b2World_IsSleepingEnabled(worldId) export function b2World_IsContinuousEnabled(worldId) { const world = b2GetWorldFromId(worldId); + return world.enableContinuous; } @@ -2119,6 +2121,7 @@ export function b2World_IsContinuousEnabled(worldId) export function b2World_GetRestitutionThreshold(worldId) { const world = b2GetWorldFromId(worldId); + return world.restitutionThreshold; } @@ -2132,6 +2135,7 @@ export function b2World_GetRestitutionThreshold(worldId) export function b2World_GetHitEventThreshold(worldId) { const world = b2GetWorldFromId(worldId); + return world.hitEventThreshold; } @@ -2145,6 +2149,7 @@ export function b2World_GetHitEventThreshold(worldId) export function b2World_IsWarmStartingEnabled(worldId) { const world = b2GetWorldFromId(worldId); + return world.enableWarmStarting; } From 2346c6912eee89f1c5d77b6a554f35e6e0eb51ce Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:18:49 -0800 Subject: [PATCH 11/14] update dist/ --- dist/PhaserBox2D-Debug.js | 3 ++- dist/PhaserBox2D-Debug.js.map | 4 ++-- dist/PhaserBox2D-Render.js | 3 ++- dist/PhaserBox2D-Render.js.map | 4 ++-- dist/PhaserBox2D.js | 3 ++- dist/PhaserBox2D.min.js | 4 ++-- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dist/PhaserBox2D-Debug.js b/dist/PhaserBox2D-Debug.js index ddc28b1..5e10632 100644 --- a/dist/PhaserBox2D-Debug.js +++ b/dist/PhaserBox2D-Debug.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:39 + * Saturday, 18 January 2025 at 09:17 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -16383,6 +16383,7 @@ function CreatePolygonFromVertices(data) { b2CreatePolygonShape(body.bodyId, shapeDef, nGon); } }); + return body; } function CreatePhysicsEditorShape(data) { const key = data.key; diff --git a/dist/PhaserBox2D-Debug.js.map b/dist/PhaserBox2D-Debug.js.map index 150296d..127c9cd 100644 --- a/dist/PhaserBox2D-Debug.js.map +++ b/dist/PhaserBox2D-Debug.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": "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", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n\n return body;\n}\n\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D-Render.js b/dist/PhaserBox2D-Render.js index 3e3a55f..ba47f35 100644 --- a/dist/PhaserBox2D-Render.js +++ b/dist/PhaserBox2D-Render.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:39 + * Saturday, 18 January 2025 at 09:17 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -15748,6 +15748,7 @@ function CreatePolygonFromVertices(data) { b2CreatePolygonShape(body.bodyId, shapeDef, nGon); } }); + return body; } function CreatePhysicsEditorShape(data) { const key = data.key; diff --git a/dist/PhaserBox2D-Render.js.map b/dist/PhaserBox2D-Render.js.map index 61e249d..4d5e071 100644 --- a/dist/PhaserBox2D-Render.js.map +++ b/dist/PhaserBox2D-Render.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/math_functions_c.js", "../src/include/math_functions_h.js", "../src/include/base_h.js", "../src/core_c.js", "../src/include/core_h.js", "../src/include/id_h.js", "../src/include/collision_h.js", "../src/table_c.js", "../src/include/table_h.js", "../src/stack_allocator_c.js", "../src/allocate_c.js", "../src/types_c.js", "../src/include/types_h.js", "../src/id_pool_c.js", "../src/distance_c.js", "../src/hull_c.js", "../src/geometry_c.js", "../src/shape_c.js", "../src/include/shape_h.js", "../src/bitset_c.js", "../src/include/bitset_h.js", "../src/constraint_graph_c.js", "../src/contact_solver_c.js", "../src/aabb_c.js", "../src/dynamic_tree_c.js", "../src/include/dynamic_tree_h.js", "../src/include/ctz_h.js", "../src/solver_set_c.js", "../src/solver_c.js", "../src/distance_joint_c.js", "../src/prismatic_joint_c.js", "../src/revolute_joint_c.js", "../src/wheel_joint_c.js", "../src/motor_joint_c.js", "../src/mouse_joint_c.js", "../src/weld_joint_c.js", "../src/joint_c.js", "../src/include/joint_h.js", "../src/island_c.js", "../src/body_c.js", "../src/include/body_h.js", "../src/block_array_c.js", "../src/manifold_c.js", "../src/contact_c.js", "../src/include/contact_h.js", "../src/broad_phase_c.js", "../src/world_c.js", "../src/include/world_h.js", "../src/physics.js", "../src/debug_draw.js", "../src/ragdoll.js", "../src/fun_stuff.js", "../src/main.js"], - "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], - "mappings": "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", + "sourcesContent": ["/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2IsNormalized, b2Length, b2Vec2, eps } from \"./include/math_functions_h.js\";\n\n/**\n * @namespace MathFunctions\n */\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nexport function b2IsValid(a)\n{\n return !isNaN(a) && isFinite(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nexport function b2Vec2_IsValid(v)\n{\n return !isNaN(v.x) && !isNaN(v.y) && isFinite(v.x) && isFinite(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q4 - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nexport function b2Rot_IsValid(q)\n{\n if (isNaN(q.s) || isNaN(q.c) || !isFinite(q.s) || !isFinite(q.c))\n {\n return false;\n }\n\n return b2IsNormalized(q);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {(b2Vec2|boolean)} Returns a new normalized b2Vec2 if successful, or false if the input is null.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nexport function b2Normalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nexport function b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n // B2_ASSERT(false);\n return new b2Vec2( 0, 0 );\n }\n\n const invLength = 1.0 / length;\n\n return new b2Vec2( invLength * v.x, invLength * v.y );\n}\n\n/**\n * Calculates the length of a vector and returns its normalized form.\n * @function b2GetLengthAndNormalize\n * @param {b2Vec2} v - The input vector to normalize\n * @returns {{length: number, normal: b2Vec2}} An object containing:\n * - length: The original length of the vector\n * - normal: A normalized vector (unit length) in the same direction as v.\n * Returns (0,0) if the input vector length is below epsilon\n */\nexport function b2GetLengthAndNormalize(v)\n{\n const length = b2Length(v);\n\n if (length < eps)\n {\n return { length: 0, normal: new b2Vec2(0, 0) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n }\n\n const invLength = 1.0 / length;\n\n return { length: length, normal: new b2Vec2( invLength * v.x, invLength * v.y ) };// PJB: the C version returns the vec2 here and the length via parameter float* length\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2GetLengthAndNormalize } from '../math_functions_c.js';\n\nexport const B2_PI = 3.14159265359;\nexport const eps = 1.0e-10;\nexport const epsSqr = eps * eps;\n\nexport const GlobalDebug = {\n b2Vec2Count: 0,\n b2Rot2Count: 0,\n b2ManifoldCount: 0,\n b2ManifoldPointCount: 0,\n b2FrameCount: 0,\n b2PolyCollideCount: 0,\n b2ContactSimCount: 0,\n b2TOIInputCount: 0,\n b2ShapeCastPairInputCount: 0,\n b2SweepCount: 0\n};\n\nexport const b2Vec2Where = {\n calls: {}\n};\n\nexport const b2Rot2Where = {\n calls: {}\n};\n\nexport const b2ManifoldPointWhere = {\n calls: {}\n};\n\nexport const b2ManifoldWhere = {\n calls: {}\n};\n\n/**\n * @class b2Vec2\n * @summary 2D vector This can be used to represent a point or free vector\n * @property {number} x - x coordinate\n * @property {number} y - y coordinate\n */\nclass b2Vec2\n{\n constructor(x = 0, y = 0)\n {\n // track number created\n // GlobalDebug.b2Vec2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Vec2Where.calls[key] == undefined) b2Vec2Where.calls[key] = 0;\n // b2Vec2Where.calls[key]++;\n\n this.x = x;\n this.y = y;\n }\n\n copy(v)\n {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n }\n\n clone()\n {\n return new b2Vec2(this.x, this.y);\n }\n}\n\n/**\n * @class b2Rot\n * @summary 2D rotation. This is similar to using a complex number for rotation\n * @property {number} s - The sine component of the rotation\n * @property {number} c - The cosine component of the rotation\n */\nclass b2Rot\n{\n constructor(c = 1, s = 0)\n {\n // track number created\n // GlobalDebug.b2Rot2Count++;\n\n // // track where they were created\n // const lines = new Error().stack.split('\\n');\n // const [, file1, line1, column1] = (lines[1] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const [, file2, line2, column2] = (lines[2] || '').match(/[@](\\S+):(\\d+):(\\d+)/) || [];\n // const key = `${file1}:${line1} <- ${file2}:${line2}`;\n // if (b2Rot2Where.calls[key] == undefined) b2Rot2Where.calls[key] = 0;\n // b2Rot2Where.calls[key]++;\n\n this.c = c;\n this.s = s;\n }\n\n copy(r)\n {\n this.c = r.c;\n this.s = r.s;\n\n return this;\n }\n\n clone()\n {\n return new b2Rot(this.c, this.s);\n }\n}\n\n/**\n * @class b2Transform\n * @summary A 2D rigid transform\n * @property {b2Vec2} p - Position vector\n * @property {b2Rot} q - Rotation component\n */\nclass b2Transform\n{\n constructor(p = null, q = null)\n {\n this.p = p;\n this.q = q;\n }\n\n static identity()\n {\n return new b2Transform(new b2Vec2(), new b2Rot());\n }\n\n clone()\n {\n const xf = new b2Transform(this.p, this.q);\n\n return xf;\n }\n\n deepClone()\n {\n const xf = new b2Transform(this.p.clone(), this.q.clone());\n\n return xf;\n }\n}\n\n/**\n * @class b2Mat22\n * @summary A 2-by-2 Matrix\n * @property {b2Vec2} cy - Matrix columns\n */\nclass b2Mat22\n{\n constructor(cx = new b2Vec2(), cy = new b2Vec2())\n {\n this.cx = cx;\n this.cy = cy;\n }\n\n clone()\n {\n return new b2Mat22(this.cx.clone(), this.cy.clone());\n }\n}\n\n/**\n * @class b2AABB\n * @summary Axis-aligned bounding box\n * @property {b2Vec2} lowerBound - The lower vertex of the bounding box\n * @property {b2Vec2} upperBound - The upper vertex of the bounding box\n */\nclass b2AABB\n{\n constructor(lowerx = 0, lowery = 0, upperx = 0, uppery = 0)\n {\n this.lowerBoundX = lowerx;\n this.lowerBoundY = lowery;\n this.upperBoundX = upperx;\n this.upperBoundY = uppery;\n }\n}\n\n// Constants\n// PJB replaced with 'new' in each case. TODO: use an improved const as suggested by Claude\n// const b2Rot_identity = new b2Rot(1, 0);\n// const b2Transform_identity = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n// const b2Mat22_zero = new b2Mat22(new b2Vec2(0, 0), new b2Vec2(0, 0));\n\n// Inline functions\n\n/**\n * @summary Returns the minimum of two numbers.\n * @function b2MinFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The smaller of the two input numbers\n */\nfunction b2MinFloat(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two numbers.\n * @function b2MaxFloat\n * @param {number} a - First number to compare\n * @param {number} b - Second number to compare\n * @returns {number} The maximum value between a and b\n */\nfunction b2MaxFloat(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of a number\n * @function b2AbsFloat\n * @param {number} a - The input number\n * @returns {number} The absolute value of the input\n * @description\n * An implementation of absolute value that returns the positive magnitude\n * of the input number.\n */\nfunction b2AbsFloat(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * @summary Clamps a floating point value between a lower and upper bound.\n * @function b2ClampFloat\n * @param {number} a - The value to clamp\n * @param {number} lower - The lower bound\n * @param {number} upper - The upper bound\n * @returns {number} The clamped value between lower and upper bounds\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampFloat(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Returns the smaller of two integers.\n * @function b2MinInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The smaller of the two input integers\n * @description\n * A comparison function that returns the minimum value between two integers\n * using a ternary operator.\n */\nfunction b2MinInt(a, b)\n{\n return a < b ? a : b;\n}\n\n/**\n * @summary Returns the larger of two integers.\n * @function b2MaxInt\n * @param {number} a - First integer to compare\n * @param {number} b - Second integer to compare\n * @returns {number} The larger of the two input integers\n */\nfunction b2MaxInt(a, b)\n{\n return a > b ? a : b;\n}\n\n/**\n * @summary Returns the absolute value of an integer.\n * @function b2AbsInt\n * @param {number} a - The integer input value.\n * @returns {number} The absolute value of the input.\n * @description\n * Computes the absolute value of an integer using conditional logic rather than Math.abs().\n */\nfunction b2AbsInt(a)\n{\n return a < 0 ? -a : a;\n}\n\n/**\n * Clamps an integer value between a lower and upper bound.\n * @function b2ClampInt\n * @param {number} a - The integer value to clamp\n * @param {number} lower - The lower bound (inclusive)\n * @param {number} upper - The upper bound (inclusive)\n * @returns {number} The clamped integer value\n * @description\n * Returns lower if a < lower, upper if a > upper, otherwise returns a.\n */\nfunction b2ClampInt(a, lower, upper)\n{\n return a < lower ? lower : (a > upper ? upper : a);\n}\n\n/**\n * @summary Calculates the dot product of two 2D vectors.\n * @function b2Dot\n * @param {b2Vec2} a - First 2D vector.\n * @param {b2Vec2} b - Second 2D vector.\n * @returns {number} The dot product of vectors a and b.\n * @description\n * Computes the dot product (scalar product) of two 2D vectors using the formula:\n * dot = a.x * b.x + a.y * b.y\n */\nfunction b2Dot(a, b)\n{\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Computes the 2D cross product of two vectors.\n * @function b2Cross\n * @param {b2Vec2} a - The first 2D vector\n * @param {b2Vec2} b - The second 2D vector\n * @returns {number} The cross product (a.x * b.y - a.y * b.x)\n * @description\n * Calculates the cross product between two 2D vectors, which represents\n * the signed area of the parallelogram formed by these vectors.\n */\nfunction b2Cross(a, b)\n{\n return a.x * b.y - a.y * b.x;\n}\n\n/**\n * @summary Performs a cross product between a 2D vector and a scalar.\n * @function b2CrossVS\n * @param {b2Vec2} v - The input vector\n * @param {number} s - The scalar value\n * @returns {b2Vec2} A new vector where x = s * v.y and y = -s * v.x\n * @description\n * Computes the cross product of a vector and scalar, returning a new vector\n * that is perpendicular to the input vector and scaled by the scalar value.\n */\nfunction b2CrossVS(v, s)\n{\n return new b2Vec2(s * v.y, -s * v.x);\n}\n\n/**\n * Performs a cross product between a scalar and a 2D vector.\n * @function b2CrossSV\n * @param {number} s - The scalar value\n * @param {b2Vec2} v - The 2D vector\n * @returns {b2Vec2} A new vector perpendicular to the input vector, scaled by s\n * @description\n * Computes s \u00D7 v, where \u00D7 denotes the cross product.\n * The result is a new vector (-s * v.y, s * v.x).\n */\nfunction b2CrossSV(s, v)\n{\n return new b2Vec2(-s * v.y, s * v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees counter-clockwise.\n * @function b2LeftPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees counter-clockwise.\n * @description\n * Creates a new vector that is perpendicular to the input vector by rotating it\n * 90 degrees counter-clockwise. The new vector is computed by setting the x component\n * to the negative y component of the input, and the y component to the x component\n * of the input.\n */\nfunction b2LeftPerp(v)\n{\n return new b2Vec2(-v.y, v.x);\n}\n\n/**\n * @summary Returns a vector rotated 90 degrees clockwise.\n * @function b2RightPerp\n * @param {b2Vec2} v - The input vector to rotate.\n * @returns {b2Vec2} A new vector perpendicular to the input, rotated 90 degrees clockwise.\n * @description\n * Creates a new vector that is perpendicular (rotated 90 degrees clockwise) to the input vector.\n * For a vector (x,y), returns (y,-x).\n */\nfunction b2RightPerp(v)\n{\n return new b2Vec2(v.y, -v.x);\n}\n\n/**\n * @summary Adds two 2D vectors.\n * @function b2Add\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing the sum of the input vectors (a + b).\n * @description\n * Creates a new b2Vec2 where the x and y components are the sums of the\n * corresponding components of the input vectors.\n */\nfunction b2Add(a, b)\n{\n return new b2Vec2(a.x + b.x, a.y + b.y);\n}\n\n/**\n * @summary Subtracts two 2D vectors.\n * @function b2Sub\n * @param {b2Vec2} a - The first vector.\n * @param {b2Vec2} b - The second vector.\n * @returns {b2Vec2} A new vector representing (a - b).\n * @description\n * Creates a new 2D vector by subtracting the components of vector b from vector a.\n * The resulting vector has coordinates (a.x - b.x, a.y - b.y).\n */\nfunction b2Sub(a, b)\n{\n return new b2Vec2(a.x - b.x, a.y - b.y);\n}\n\n/**\n * @summary Returns the negation of a 2D vector.\n * @function b2Neg\n * @param {b2Vec2} a - The input vector to negate.\n * @returns {b2Vec2} A new vector with components (-a.x, -a.y).\n * @description\n * Creates a new b2Vec2 with the negated x and y components of the input vector.\n */\nfunction b2Neg(a)\n{\n return new b2Vec2(-a.x, -a.y);\n}\n\n/**\n * @function b2Lerp\n * @summary Performs linear interpolation between two 2D vectors.\n * @param {b2Vec2} a - The starting vector\n * @param {b2Vec2} b - The ending vector\n * @param {number} t - The interpolation parameter between 0 and 1\n * @returns {b2Vec2} A new vector representing the interpolated point\n * @description\n * Calculates a point that lies on the straight line between vectors a and b,\n * where t=0 returns a, t=1 returns b, and values in between return proportionally\n * interpolated points.\n */\nfunction b2Lerp(a, b, t)\n{\n return new b2Vec2((1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y);\n}\n\n/**\n * @summary Performs component-wise multiplication of two 2D vectors.\n * @function b2Mul\n * @param {b2Vec2} a - First 2D vector with x and y components.\n * @param {b2Vec2} b - Second 2D vector with x and y components.\n * @returns {b2Vec2} A new vector where each component is the product of the corresponding components of a and b.\n * @description\n * Multiplies the x components of both vectors together and the y components of both vectors together,\n * returning a new b2Vec2 with these products as its components.\n */\nfunction b2Mul(a, b)\n{\n return new b2Vec2(a.x * b.x, a.y * b.y);\n}\n\n/**\n * @summary Multiplies a scalar value with a 2D vector.\n * @function b2MulSV\n * @param {number} s - The scalar value to multiply with the vector.\n * @param {b2Vec2} v - The 2D vector to be multiplied.\n * @returns {b2Vec2} A new b2Vec2 representing the scaled vector (s * v).\n * @description\n * Performs scalar multiplication on a 2D vector, where each component\n * of the vector is multiplied by the scalar value.\n */\nfunction b2MulSV(s, v)\n{\n return new b2Vec2(s * v.x, s * v.y);\n}\n\n/**\n * @function b2MulAdd\n * @summary Performs vector addition with scalar multiplication (a + s * b).\n * @param {b2Vec2} a - First vector operand\n * @param {number} s - Scalar multiplier\n * @param {b2Vec2} b - Second vector operand\n * @returns {b2Vec2} A new vector representing the result of a + s * b\n */\nfunction b2MulAdd(a, s, b)\n{\n return new b2Vec2(a.x + s * b.x, a.y + s * b.y);\n}\n\nfunction b2MulAddOut(a, s, b, out)\n{\n out.x = a.x + s * b.x;\n out.y = a.y + s * b.y;\n}\n\n/**\n * @function b2MulSub\n * @summary Performs vector subtraction with scalar multiplication: a - s * b\n * @param {b2Vec2} a - The first vector operand\n * @param {number} s - The scalar multiplier\n * @param {b2Vec2} b - The second vector operand\n * @returns {b2Vec2} A new vector representing the result of a - s * b\n */\nfunction b2MulSub(a, s, b)\n{\n return new b2Vec2(a.x - s * b.x, a.y - s * b.y);\n}\n\nfunction b2DotSub(sub1, sub2, dot)\n{\n const subX = sub1.x - sub2.x;\n const subY = sub1.y - sub2.y;\n\n return subX * dot.x + subY * dot.y;\n}\n\n/**\n * Returns a new b2Vec2 with the absolute values of the input vector's components.\n * @function b2Abs\n * @param {b2Vec2} a - The input vector whose components will be converted to absolute values.\n * @returns {b2Vec2} A new vector containing the absolute values of the input vector's x and y components.\n */\nfunction b2Abs(a)\n{\n return new b2Vec2(Math.abs(a.x), Math.abs(a.y));\n}\n\n/**\n * @function b2Min\n * @summary Returns a new vector containing the minimum x and y components from two vectors.\n * @param {b2Vec2} a - First 2D vector\n * @param {b2Vec2} b - Second 2D vector\n * @returns {b2Vec2} A new vector with x = min(a.x, b.x) and y = min(a.y, b.y)\n */\nfunction b2Min(a, b)\n{\n return new b2Vec2(Math.min(a.x, b.x), Math.min(a.y, b.y));\n}\n\n/**\n * @function b2Max\n * @summary Returns a new vector containing the component-wise maximum values from two vectors.\n * @param {b2Vec2} a - First input vector\n * @param {b2Vec2} b - Second input vector\n * @returns {b2Vec2} A new vector where each component is the maximum of the corresponding components from vectors a and b\n * @description\n * Creates a new b2Vec2 where:\n * - x component is the maximum of a.x and b.x\n * - y component is the maximum of a.y and b.y\n */\nfunction b2Max(a, b)\n{\n return new b2Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y));\n}\n\n/**\n * @function b2Clamp\n * @summary Clamps a 2D vector's components between minimum and maximum bounds.\n * @param {b2Vec2} v - The vector to clamp\n * @param {b2Vec2} a - The minimum bounds vector\n * @param {b2Vec2} b - The maximum bounds vector\n * @returns {b2Vec2} A new vector with components clamped between a and b\n * @description\n * Creates a new 2D vector where each component (x,y) is clamped between\n * the corresponding components of vectors a and b. Uses b2ClampFloat\n * internally to clamp individual components.\n */\nfunction b2Clamp(v, a, b)\n{\n return new b2Vec2(\n b2ClampFloat(v.x, a.x, b.x),\n b2ClampFloat(v.y, a.y, b.y)\n );\n}\n\n/**\n * @summary Calculates the length (magnitude) of a 2D vector.\n * @function b2Length\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The scalar length of the vector.\n * @description\n * Computes the Euclidean length of a 2D vector using the formula sqrt(x\u00B2 + y\u00B2).\n */\nfunction b2Length(v)\n{\n return Math.sqrt(v.x * v.x + v.y * v.y);\n}\n\nfunction b2LengthXY(x, y)\n{\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * @summary Calculates the squared length (magnitude) of a 2D vector.\n * @function b2LengthSquared\n * @param {b2Vec2} v - A 2D vector with x and y components.\n * @returns {number} The squared length of the vector (x\u00B2 + y\u00B2).\n * @description\n * Computes the dot product of a vector with itself, which gives the squared\n * length of the vector without performing a square root operation.\n */\nfunction b2LengthSquared(v)\n{\n return v.x * v.x + v.y * v.y;\n}\n\n/**\n * @function b2Distance\n * @summary Calculates the Euclidean distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The distance between points a and b\n * @description\n * Computes the straight-line distance between two points using the Pythagorean theorem.\n */\nfunction b2Distance(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * @function b2DistanceSquared\n * @summary Calculates the squared distance between two 2D points.\n * @param {b2Vec2} a - The first 2D vector point\n * @param {b2Vec2} b - The second 2D vector point\n * @returns {number} The squared distance between points a and b\n * @description\n * Computes the squared Euclidean distance between two points without taking the square root.\n * The calculation is (b.x - a.x)\u00B2 + (b.y - a.y)\u00B2\n */\nfunction b2DistanceSquared(a, b)\n{\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n\n return dx * dx + dy * dy;\n}\n\n/**\n * Creates a new b2Rot object representing a 2D rotation.\n * @function b2MakeRot\n * @param {number} angle - The rotation angle in radians\n * @returns {b2Rot} A new b2Rot object containing the cosine and sine of the input angle\n * @description\n * Constructs a b2Rot object by computing the cosine and sine of the provided angle.\n * The resulting b2Rot contains these values as its 'c' and 's' components respectively.\n */\nfunction b2MakeRot(angle)\n{\n return new b2Rot(Math.cos(angle), Math.sin(angle));\n}\n\n/**\n * Normalizes a rotation by scaling its components to create a unit vector.\n * @function b2NormalizeRot\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @returns {b2Rot} A new normalized b2Rot object where the components form a unit vector\n * @description\n * Computes the magnitude of the rotation vector and divides both components by it\n * to create a normalized rotation. If the magnitude is 0, returns a default rotation.\n */\nfunction b2NormalizeRot(q)\n{\n const mag = Math.sqrt(q.s * q.s + q.c * q.c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q.c * invMag, q.s * invMag);\n}\n\nfunction b2InvMagRot(c, s)\n{\n const mag = Math.sqrt(s * s + c * c);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return invMag;\n}\n\n/**\n * @function b2IsNormalized\n * @summary Checks if a rotation is properly normalized.\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is normalized within a tolerance of 6e-4\n * @description\n * Verifies that the sum of squares of the sine and cosine components\n * equals 1 within a tolerance of \u00B16e-4, which indicates a valid rotation.\n */\nfunction b2IsNormalized(q)\n{\n const qq = q.s * q.s + q.c * q.c;\n\n return 1 - 0.0006 < qq && qq < 1 + 0.0006;\n}\n\n/**\n * @function b2NLerp\n * @summary Performs normalized linear interpolation between two rotations.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} t - Interpolation factor between 0 and 1\n * @returns {b2Rot} The normalized interpolated rotation\n * @description\n * Linearly interpolates between two rotations and normalizes the result.\n * When t=0 returns q12, when t=1 returns q22.\n */\nfunction b2NLerp(q1, q2, t)\n{\n const omt = 1 - t;\n const q = new b2Rot(\n omt * q1.c + t * q2.c,\n omt * q1.s + t * q2.s\n );\n\n return b2NormalizeRot(q);\n}\n\n/**\n * @function b2IntegrateRotation\n * @summary Integrates a rotation by a specified angle while maintaining normalization.\n * @param {b2Rot} q1 - The initial rotation.\n * @param {number} deltaAngle - The angle to rotate by, in radians.\n * @returns {b2Rot} A new normalized rotation after applying the integration.\n * @description\n * Performs rotation integration while ensuring the resulting rotation remains\n * normalized through magnitude scaling. The function handles the case where\n * magnitude could be zero by returning a default rotation.\n */\nfunction b2IntegrateRotation(q1, deltaAngle)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n\n return new b2Rot(q2C * invMag, q2S * invMag);\n}\n\nfunction b2IntegrateRotationOut(q1, deltaAngle, out)\n{\n const q2C = q1.c - deltaAngle * q1.s;\n const q2S = q1.s + deltaAngle * q1.c;\n const mag = Math.sqrt(q2S * q2S + q2C * q2C);\n const invMag = mag > 0 ? 1 / mag : 0;\n out.c = q2C * invMag;\n out.s = q2S * invMag;\n}\n\n/**\n * @function b2ComputeAngularVelocity\n * @summary Computes the angular velocity between two rotations given a time step.\n * @param {b2Rot} q1 - The first rotation\n * @param {b2Rot} q2 - The second rotation\n * @param {number} inv_h - The inverse of the time step (1/dt)\n * @returns {number} The computed angular velocity in radians per second\n * @description\n * Calculates the angular velocity by comparing two rotations and dividing by the time step.\n * Uses the formula (\u03B82 - \u03B81)/dt where \u03B8 is extracted from the rotations using their sine\n * and cosine components.\n */\nfunction b2ComputeAngularVelocity(q1, q2, inv_h)\n{\n return inv_h * (q2.s * q1.c - q2.c * q1.s);\n}\n\n/**\n * @function b2Rot_GetAngle\n * @summary Gets the angle of a rotation object in radians.\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components.\n * @returns {number} The angle in radians, calculated using arctangent of s/c.\n * @description\n * Calculates the angle of a rotation by computing the arctangent of the sine\n * component divided by the cosine component using Math.atan2.\n */\nfunction b2Rot_GetAngle(q)\n{\n return Math.atan2(q.s, q.c);\n}\n\n/**\n * Returns the x-axis vector from a rotation matrix.\n * @function b2Rot_GetXAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector representing the x-axis direction (c, s)\n * @description\n * Extracts the x-axis direction vector from a rotation matrix by returning\n * a vector containing the cosine component in x and sine component in y.\n */\nfunction b2Rot_GetXAxis(q)\n{\n return new b2Vec2(q.c, q.s);\n}\n\n/**\n * Returns the Y axis vector from a rotation matrix.\n * @function b2Rot_GetYAxis\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @returns {b2Vec2} A 2D vector (-sin, cos) representing the Y axis of the rotation\n * @description\n * Extracts the Y axis vector from a rotation matrix by returning the vector (-sin, cos).\n * This represents the vertical basis vector of the rotated coordinate system.\n */\nfunction b2Rot_GetYAxis(q)\n{\n return new b2Vec2(-q.s, q.c);\n}\n\n/**\n * @function b2MulRot\n * @summary Multiplies two rotations together.\n * @param {b2Rot} q - First rotation\n * @param {b2Rot} r - Second rotation\n * @returns {b2Rot} A new rotation representing the product of the two input rotations\n * @description\n * Performs rotation multiplication by combining the cosine and sine components\n * of two b2Rot objects using the formula:\n * result.c = q4.c * r.c - q4.s * r.s\n * result.s = q4.s * r.c + q4.c * r.s\n */\nfunction b2MulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c - q.s * r.s,\n q.s * r.c + q.c * r.s\n );\n}\n\nfunction b2MulRotC(q, r)\n{\n return q.c * r.c - q.s * r.s;\n}\n\nfunction b2MulRotS(q, r)\n{\n return q.s * r.c + q.c * r.s;\n}\n\n/**\n * @function b2InvMulRot\n * @summary Multiplies the inverse of the first rotation with the second rotation.\n * @param {b2Rot} q - The first rotation to be inverted\n * @param {b2Rot} r - The second rotation to be multiplied\n * @returns {b2Rot} A new rotation representing q^-1 * r\n * @description\n * Computes the product of the inverse of rotation q with rotation r.\n * For rotations, the inverse multiplication is equivalent to using the transpose\n * of the rotation matrix.\n */\nfunction b2InvMulRot(q, r)\n{\n return new b2Rot(\n q.c * r.c + q.s * r.s,\n q.c * r.s - q.s * r.c\n );\n}\n\n/**\n * @function b2RelativeAngle\n * @summary Calculates the relative angle between two rotations.\n * @param {b2Rot} b - The first rotation\n * @param {b2Rot} a - The second rotation\n * @returns {number} The relative angle in radians between the two rotations\n * @description\n * Computes the angle between two rotations by using their sine and cosine components.\n * The result is the angle needed to rotate from rotation 'a' to rotation 'b'.\n */\nfunction b2RelativeAngle(b, a)\n{\n const s = b.s * a.c - b.c * a.s;\n const c = b.c * a.c + b.s * a.s;\n\n return Math.atan2(s, c);\n}\n\n/**\n * @function b2UnwindAngle\n * @summary Normalizes an angle to be within the range [-\u03C0, \u03C0].\n * @param {number} angle - The input angle in radians to normalize.\n * @returns {number} The normalized angle in radians within the range [-\u03C0, \u03C0].\n * @description\n * This function takes an angle in radians and ensures it falls within the range [-\u03C0, \u03C0]\n * by adding or subtracting 2\u03C0 as needed. If the input angle is already within\n * the valid range, it is returned unchanged.\n */\nfunction b2UnwindAngle(angle)\n{\n if (angle < -B2_PI)\n {\n return angle + 2 * B2_PI;\n }\n else if (angle > B2_PI)\n {\n return angle - 2 * B2_PI;\n }\n\n return angle;\n}\n\n/**\n * @function b2RotateVector\n * @summary Rotates a 2D vector by a given rotation\n * @param {b2Rot} q - A rotation object containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to rotate\n * @returns {b2Vec2} A new vector representing the rotated result\n * @description\n * Applies a 2D rotation to a vector using the formula:\n * x' = c*x - s*y\n * y' = s*x + c*y\n * where (x,y) is the input vector and (c,s) represents the rotation\n */\nfunction b2RotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2InvRotateVector\n * @summary Performs an inverse rotation of a vector using a rotation matrix\n * @param {b2Rot} q - A rotation matrix containing cosine (c) and sine (s) components\n * @param {b2Vec2} v - The vector to be inversely rotated\n * @returns {b2Vec2} A new vector representing the inverse rotation of v by q4\n * @description\n * Applies the inverse of the rotation defined by q4 to vector v.\n * The operation is equivalent to multiplying the vector by the transpose\n * of the rotation matrix represented by q4.\n */\nfunction b2InvRotateVector(q, v)\n{\n return new b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);\n}\n\n/**\n * @function b2TransformPoint\n * @summary Transforms a point using a rigid body transform.\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The transformed point\n * @description\n * Applies a rigid body transformation to a 2D point. The transformation consists of\n * a rotation followed by a translation. The rotation is applied using the rotation\n * matrix stored in t.q (cosine and sine components), and the translation is applied\n * using the position vector stored in t.p.\n */\nfunction b2TransformPoint(t, p)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n return new b2Vec2(x, y);\n}\n\nfunction b2TransformPointOut(t, p, out)\n{\n const x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n const y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n\n // safe: i.e. out = t.p\n out.x = x;\n out.y = y;\n}\n\nfunction b2TransformPointOutXf(t, p, out)\n{\n out.p.x = (t.q.c * p.x - t.q.s * p.y) + t.p.x;\n out.p.y = (t.q.s * p.x + t.q.c * p.y) + t.p.y;\n out.q.c = t.q.c;\n out.q.s = t.q.s;\n}\n\n/**\n * Applies an inverse transform to a point.\n * @function b2InvTransformPoint\n * @param {b2Transform} t - A transform containing position (p) and rotation (q) components\n * @param {b2Vec2} p - The point to transform\n * @returns {b2Vec2} The inverse transformed point\n * @description\n * Computes the inverse transform of a point by first translating relative to the transform's\n * position, then applying the inverse rotation. The rotation inverse is computed using\n * the transpose of the rotation matrix.\n */\nfunction b2InvTransformPoint(t, p)\n{\n const vx = p.x - t.p.x;\n const vy = p.y - t.p.y;\n\n return new b2Vec2(t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy);\n}\n\n/**\n * @function b2MulTransforms\n * @summary Multiplies two transforms together to create a new transform.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform C that represents the multiplication of A and B\n * @description\n * Combines two transforms by first multiplying their rotations (q components),\n * then rotating B's position vector by A's rotation and adding it to A's position.\n * The result represents the combined transformation of first applying B, then A.\n */\nfunction b2MulTransforms(A, B)\n{\n const C = new b2Transform();\n C.q = b2MulRot(A.q, B.q);\n C.p = b2Add(b2RotateVector(A.q, B.p), A.p);\n\n return C;\n}\n\n/**\n * @function b2InvMulTransforms\n * @summary Computes the inverse multiplication of two transforms.\n * @param {b2Transform} A - The first transform\n * @param {b2Transform} B - The second transform\n * @returns {b2Transform} A new transform representing the inverse multiplication of A and B\n * @description\n * Calculates A^-1 * B, where A^-1 is the inverse of transform A.\n * The result combines both the rotational and translational components\n * of the transforms using their quaternion and position vectors.\n */\nfunction b2InvMulTransforms(A, B)\n{\n const C = new b2Transform(new b2Vec2(), new b2Rot());\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n\n return C;\n}\n\nfunction b2InvMulTransformsOut(A, B, out)\n{\n const C = out;\n\n // C.q = b2InvMulRot(A.q, B.q);\n // q.c * r.c + q.s * r.s, q.c * r.s - q.s * r.c\n C.q.c = A.q.c * B.q.c + A.q.s * B.q.s;\n C.q.s = A.q.c * B.q.s - A.q.s * B.q.c;\n\n // C.p = b2InvRotateVector(A.q, b2Sub(B.p, A.p));\n // q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y\n const subX = B.p.x - A.p.x;\n const subY = B.p.y - A.p.y;\n C.p.x = A.q.c * subX + A.q.s * subY;\n C.p.y = -A.q.s * subX + A.q.c * subY;\n}\n\n/**\n * @function b2MulMV\n * @summary Multiplies a 2x2 matrix by a 2D vector.\n * @param {b2Mat22} A - A 2x2 matrix with components cx and cy, each containing x and y values\n * @param {b2Vec2} v - A 2D vector with x and y components\n * @returns {b2Vec2} The resulting 2D vector from the matrix-vector multiplication\n * @description\n * Performs matrix-vector multiplication of the form Av, where A is a 2x2 matrix\n * and v is a 2D vector. The result is a new 2D vector.\n */\nfunction b2MulMV(A, v)\n{\n return new b2Vec2(\n A.cx.x * v.x + A.cy.x * v.y,\n A.cx.y * v.x + A.cy.y * v.y\n );\n}\n\n/**\n * Calculates the inverse of a 2x2 matrix.\n * @function b2GetInverse22\n * @param {b2Mat22} A - The input 2x2 matrix to invert\n * @returns {b2Mat22} The inverse of matrix A. If the determinant is 0, returns a matrix with undefined values\n * @description\n * Computes the inverse of a 2x2 matrix using the formula:\n * For matrix [[a,b],[c,d]], inverse = (1/det) * [[d,-c],[-b,a]]\n * where det = ad-bc\n */\nfunction b2GetInverse22(A)\n{\n const a = A.cx.x,\n b = A.cy.x,\n c = A.cx.y,\n d = A.cy.y;\n let det = a * d - b * c;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Mat22(\n new b2Vec2(det * d, -det * c),\n new b2Vec2(-det * b, det * a)\n );\n}\n\n/**\n * @function b2Solve22\n * @summary Solves a 2x2 linear system of equations Ax = b using Cramer's rule.\n * @param {b2Mat22} A - A 2x2 matrix represented as two column vectors (cx, cy)\n * @param {b2Vec2} b - A 2D vector representing the right-hand side of the equation\n * @returns {b2Vec2} The solution vector x that satisfies Ax = b. Returns a zero vector if the system is singular (det = 0)\n * @description\n * Solves the system using the formula:\n * x = (1/det) * [a22 -a12] * [b.x]\n * [-a21 a11] [b.y]\n * where det = a11*a22 - a12*a21\n */\nfunction b2Solve22(A, b)\n{\n const a11 = A.cx.x,\n a12 = A.cy.x,\n a21 = A.cx.y,\n a22 = A.cy.y;\n let det = a11 * a22 - a12 * a21;\n\n if (det !== 0)\n {\n det = 1 / det;\n }\n\n return new b2Vec2(\n det * (a22 * b.x - a12 * b.y),\n det * (a11 * b.y - a21 * b.x)\n );\n}\n\n/**\n * @function b2AABB_Contains\n * @summary Determines if one Axis-Aligned Bounding Box (AABB) completely contains another.\n * @param {b2AABB} a - The containing AABB\n * @param {b2AABB} b - The AABB to test for containment\n * @returns {boolean} True if AABB 'a' completely contains AABB 'b', false otherwise\n * @description\n * Tests if AABB 'b' is completely contained within AABB 'a' by comparing their bounds.\n * An AABB contains another if its lower bounds are less than or equal to the other's lower bounds\n * and its upper bounds are greater than or equal to the other's upper bounds.\n */\nfunction b2AABB_Contains(a, b)\n{\n return (\n a.lowerBoundX <= b.lowerBoundX &&\n a.lowerBoundY <= b.lowerBoundY &&\n b.upperBoundX <= a.upperBoundX &&\n b.upperBoundY <= a.upperBoundY\n );\n}\n\n/**\n * @function b2AABB_Center\n * @summary Calculates the center point of an Axis-Aligned Bounding Box (AABB).\n * @param {b2AABB} a - The AABB object containing lowerBound and upperBound coordinates.\n * @returns {b2Vec2} A 2D vector representing the center point of the AABB.\n * @description\n * Computes the center point of an AABB by averaging its lower and upper bounds\n * in both X and Y dimensions.\n */\nfunction b2AABB_Center(a)\n{\n return new b2Vec2(\n 0.5 * (a.lowerBoundX + a.upperBoundX),\n 0.5 * (a.lowerBoundY + a.upperBoundY)\n );\n}\n\n/**\n * @summary Calculates the half-widths (extents) of an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_Extents\n * @param {b2AABB} a - The AABB to calculate extents for\n * @returns {b2Vec2} A vector containing the half-width and half-height of the AABB\n * @description\n * Computes the extents of an AABB by calculating half the difference between\n * its upper and lower bounds in both x and y dimensions.\n */\nfunction b2AABB_Extents(a)\n{\n return new b2Vec2(\n 0.5 * (a.upperBoundX - a.lowerBoundX),\n 0.5 * (a.upperBoundY - a.lowerBoundY)\n );\n}\n\n/**\n * @function b2AABB_Union\n * @summary Creates a new AABB that contains both input AABBs.\n * @param {b2AABB} a - The first axis-aligned bounding box\n * @param {b2AABB} b - The second axis-aligned bounding box\n * @returns {b2AABB} A new AABB that encompasses both input boxes\n * @description\n * Computes the union of two axis-aligned bounding boxes by creating a new AABB\n * with a lower bound at the minimum coordinates and an upper bound at the\n * maximum coordinates of both input boxes.\n */\nfunction b2AABB_Union(a, b)\n{\n const c = new b2AABB();\n c.lowerBoundX = Math.min(a.lowerBoundX, b.lowerBoundX);\n c.lowerBoundY = Math.min(a.lowerBoundY, b.lowerBoundY);\n c.upperBoundX = Math.max(a.upperBoundX, b.upperBoundX);\n c.upperBoundY = Math.max(a.upperBoundY, b.upperBoundY);\n\n return c;\n}\n\n/**\n * @summary Checks if a number is valid (finite and not NaN).\n * @function b2IsValid\n * @param {number} a - The number to validate.\n * @returns {boolean} True if the number is valid (finite and not NaN), false otherwise.\n * @description\n * This function performs a validation check on a number by ensuring it is both\n * finite and not NaN (Not a Number).\n */\nfunction b2IsValid(a)\n{\n return isFinite(a) && !isNaN(a);\n}\n\n/**\n * Validates a b2Vec2 object by checking if it exists and its components are valid numbers.\n * @function b2Vec2_IsValid\n * @param {b2Vec2} v - The vector to validate, containing x and y components.\n * @returns {boolean} True if the vector exists and both x and y components are valid numbers.\n */\nfunction b2Vec2_IsValid(v)\n{\n return v && b2IsValid(v.x) && b2IsValid(v.y);\n}\n\n/**\n * Validates a 2D rotation object.\n * @function b2Rot_IsValid\n * @param {b2Rot} q - A rotation object containing sine (s) and cosine (c) components\n * @returns {boolean} True if the rotation is valid, false otherwise\n * @description\n * Checks if a b2Rot object is valid by verifying:\n * 1. The object exists\n * 2. Both sine and cosine components contain valid numbers\n * 3. The rotation is properly normalized (s\u00B2 + c\u00B2 = 1)\n */\nfunction b2Rot_IsValid(q)\n{\n return q && b2IsValid(q.s) && b2IsValid(q.c) && b2IsNormalized(q);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nfunction b2AABB_IsValid(aabb)\n{\n if (!aabb) { return false; }\n const dx = aabb.upperBoundX - aabb.lowerBoundX;\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n const valid = dx >= 0 && dy >= 0;\n\n return valid &&\n b2IsValid(aabb.lowerBoundX) && b2IsValid(aabb.lowerBoundY) &&\n b2IsValid(aabb.upperBoundX) && b2IsValid(aabb.upperBoundY);\n}\n\n/**\n * @function b2Normalize\n * @summary Normalizes a 2D vector to unit length.\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} Returns a new normalized b2Vec2 if successful.\n * If the vector length is less than epsilon, returns a zero vector (0,0).\n * @description\n * Normalizes the input vector by dividing its components by its length.\n * If the vector's length is greater than the epsilon value, the function\n * returns a new vector with the same direction but unit length.\n */\nfunction b2Normalize(v)\n{\n if (!v) { console.assert(false); } // why would this ever happen? make sure it doesn't...\n const length = b2Length(v);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\nfunction b2NormalizeXY(x, y)\n{\n const length = Math.sqrt(x * x + y * y);\n\n if (length > eps)\n {\n const invLength = 1 / length;\n\n return new b2Vec2(x * invLength, y * invLength);\n }\n\n return new b2Vec2(0, 0);\n}\n\n/**\n * Normalizes a 2D vector and performs length validation.\n * @function b2NormalizeChecked\n * @param {b2Vec2} v - The vector to normalize.\n * @returns {b2Vec2} A new normalized vector with unit length.\n * @throws {Error} Throws an assertion error if the vector length is less than or equal to eps.\n */\nfunction b2NormalizeChecked(v)\n{\n const length = b2Length(v);\n console.assert(length > eps);\n const invLength = 1 / length;\n\n return new b2Vec2(v.x * invLength, v.y * invLength);\n}\n\nexport {\n b2Vec2, b2Rot, b2Transform, b2Mat22, b2AABB,\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat,\n b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV,\n b2LeftPerp, b2RightPerp, b2Add, b2Sub,\n b2Neg, b2Lerp, b2Mul, b2MulSV,\n b2MulAdd, b2MulSub, b2Abs, b2Min,\n b2Max, b2Clamp, b2Length, b2LengthXY, b2LengthSquared,\n b2Distance, b2DistanceSquared, b2MakeRot,\n b2NormalizeRot, b2InvMagRot,\n b2IsNormalized, b2NLerp,\n b2IntegrateRotation, b2IntegrateRotationOut,\n b2ComputeAngularVelocity,\n b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis,\n b2MulRot, b2InvMulRot, b2MulRotC, b2MulRotS,\n b2RelativeAngle, b2UnwindAngle,\n b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2TransformPointOut, b2TransformPointOutXf, b2InvTransformPoint,\n b2MulTransforms,\n b2InvMulTransforms, b2InvMulTransformsOut,\n b2MulMV, b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union,\n b2IsValid, b2Vec2_IsValid, b2Rot_IsValid, b2AABB_IsValid,\n b2Normalize, b2NormalizeXY, b2NormalizeChecked, b2GetLengthAndNormalize,\n b2DotSub, b2MulAddOut\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @class b2Version\n * @summary Version numbering scheme. See https://semver.org/\n * @property {number} major - Significant changes\n * @property {number} minor - Incremental changes\n * @property {number} revision - Bug fixes\n */\nexport class b2Version\n{\n constructor(major = 0, minor = 0, revision = 0)\n {\n // / Significant changes\n this.major = major;\n\n // / Incremental changes\n this.minor = minor;\n\n // / Bug fixes\n this.revision = revision;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Version } from './include/base_h.js';\n\n/**\n * @namespace Core\n */\n\nlet b2_lengthUnitsPerMeter = 1.0;\nconst B2_NULL_INDEX = -1;\n\nexport { B2_NULL_INDEX };\n\n/**\n * @summary Sets the length units per meter for Box2D physics calculations.\n * @function b2SetLengthUnitsPerMeter\n * @param {number} lengthUnits - The number of length units that represent one meter.\n * @returns {void}\n * @description\n * Sets the global scaling factor that defines how many length units in the physics\n * simulation correspond to one meter in the real world. This affects all subsequent\n * physics calculations in the Box2D engine.\n */\nexport function b2SetLengthUnitsPerMeter(lengthUnits)\n{\n // B2_ASSERT(b2IsValid(lengthUnits) && lengthUnits > 0.0);\n b2_lengthUnitsPerMeter = lengthUnits;\n}\n\n/**\n * @function b2GetLengthUnitsPerMeter\n * @summary Returns the global length units per meter scaling factor.\n * @returns {number} The number of length units per meter used in the physics simulation.\n * @description\n * Returns the value of b2_lengthUnitsPerMeter, which defines the conversion factor\n * between physics simulation units and real-world meters.\n */\nexport function b2GetLengthUnitsPerMeter()\n{\n return b2_lengthUnitsPerMeter;\n}\n\n/**\n * Sets the assertion function handler for Box2D.\n * @function b2SetAssertFcn\n * @param {Function|null} assertFcn - The assertion function to handle Box2D assertions.\n * If null, assertions will be disabled.\n * @returns {void}\n * @description\n * This function sets the global assertion handler used by Box2D for runtime checks.\n * The assertion handler is called when a Box2D assertion fails.\n */\nexport function b2SetAssertFcn(assertFcn)\n{\n console.warn(\"b2SetAssertFcn not supported\");\n}\n\n/**\n * @summary Returns the current version of Box2D\n * @function b2GetVersion\n * @returns {b2Version} A b2Version object containing major version 3, minor version 0, and revision 0\n * @description\n * This function creates and returns a new b2Version object initialized with Box2D version 3.0.0\n */\nexport function b2GetVersion()\n{\n return new b2Version(3, 1, 0);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport { B2_NULL_INDEX, b2GetVersion, b2SetAssertFcn, b2SetLengthUnitsPerMeter, b2GetLengthUnitsPerMeter } from '../core_c.js';\n\nexport const b2_lengthUnitsPerMeter = 1.0;\n\n// Used to detect bad values. Positions greater than about 16km will have precision\n// problems, so 100km as a limit should be fine in all cases.\nexport const B2_HUGE= 100000.0 * b2_lengthUnitsPerMeter;\n\n// Maximum number of colors in the constraint graph. Constraints that cannot\n// find a color are added to the overflow set which are solved single-threaded.\nexport const b2_graphColorCount = 2;\n\n// A small length used as a collision and constraint tolerance. Usually it is\n// chosen to be numerically significant, but visually insignificant. In meters.\n// @warning modifying this can have a significant impact on stability\nexport const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter;\n\n// Maximum number of simultaneous worlds that can be allocated\nexport const B2_MAX_WORLDS = 16;\n\n// The maximum rotation of a body per time step. This limit is very large and is used\n// to prevent numerical problems. You shouldn't need to adjust this.\n// @warning increasing this to 0.5 * Math.PI or greater will break continuous collision.\nexport const B2_MAX_ROTATION = 0.25 * Math.PI;\n\n// @warning modifying this can have a significant impact on performance and stability\nexport const b2_speculativeDistance = 4.0 * b2_linearSlop;\n\n// This is used to fatten AABBs in the dynamic tree. This allows proxies\n// to move by a small amount without triggering a tree adjustment.\n// This is in meters.\n// @warning modifying this can have a significant impact on performance\nexport const b2_aabbMargin = 0.1 * b2_lengthUnitsPerMeter;\n\n// The time that a body must be still before it will go to sleep. In seconds.\nexport const b2_timeToSleep = 0.5;\n\n// Returns the number of elements of an array\nexport function B2_ARRAY_COUNT(A)\n{\n return A.length;\n}\n\n//\n// Unsupported API features\n//\n\n/**\n * @summary Sets custom memory allocator functions for Box2D (Not supported in Phaser Box2D JS)\n * @function b2SetAllocator\n * @param {Function} allocFcn - Memory allocation function pointer\n * @param {Function} freeFcn - Memory deallocation function pointer\n * @returns {void}\n * @description\n * This function is intended to set custom memory allocation and deallocation functions\n * for Box2D. However, in the Phaser Box2D JS implementation, this functionality\n * is not supported and will only generate a warning message.\n * @throws {Warning} Outputs a console warning indicating lack of support\n */\nexport function b2SetAllocator()\n{\n console.warn(\"b2SetAllocator not supported\");\n}\n\n/**\n * @summary Returns the byte count for Box2D memory usage.\n * @function b2GetByteCount\n * @returns {number} An integer representing the total bytes used by Box2D.\n * @description\n * This function is a stub that warns users that byte count tracking is not\n * supported in the JavaScript implementation of Box2D for Phaser.\n */\nexport function b2GetByteCount()\n{\n console.warn(\"b2GetByteCount not supported\");\n}\n\n/**\n * @summary Creates a timer object for performance measurement.\n * @function b2CreateTimer\n * @returns {b2Timer} A timer object for measuring elapsed time.\n * @description\n * This function creates a timer object but is not supported in the Phaser Box2D JS implementation.\n * When called, it issues a console warning about lack of support.\n */\nexport function b2CreateTimer()\n{\n console.warn(\"b2CreateTimer not supported\");\n}\n\n/**\n * @summary Gets system ticks for timing purposes\n * @function b2GetTicks\n * @returns {number} Returns 0 since this function not supported\n * @description\n * This is a stub function that exists for compatibility with Box2D but is not\n * implemented in the Phaser Box2D JS port. It logs a warning when called.\n * @throws {Warning} Logs a console warning that the function is not supported\n */\nexport function b2GetTicks()\n{\n console.warn(\"b2GetTicks not supported\");\n}\n\n/**\n * @summary Gets the elapsed time in milliseconds.\n * @function b2GetMilliseconds\n * @returns {number} The elapsed time in milliseconds.\n * @description\n * This function is a stub that warns that millisecond timing is not supported\n * in the Phaser Box2D JS implementation.\n * @throws {Warning} Console warning indicating lack of support.\n */\nexport function b2GetMilliseconds()\n{\n console.warn(\"b2GetMilliseconds not supported\");\n}\n\n/**\n * @summary Gets elapsed milliseconds from a b2Timer and resets it.\n * @function b2GetMillisecondsAndReset\n * @param {b2Timer} timer - The Box2D timer object to query and reset\n * @returns {number} The elapsed time in milliseconds\n * @description\n * This function returns the elapsed milliseconds from a Box2D timer object and resets it.\n * In the JavaScript implementation for Phaser Box2D, this functionality is not supported\n * and will trigger a warning.\n * @throws {Warning} Logs a console warning that this function is not supported\n */\nexport function b2GetMillisecondsAndReset(timer)\n{\n console.warn(\"b2GetMillisecondsAndReset not supported\");\n}\n\n/**\n * @summary Placeholder function for sleep functionality in Box2D JS\n * @function b2SleepMilliseconds\n * @param {number} ms - The number of milliseconds to sleep\n * @returns {void}\n * @description\n * This function is a stub that issues a warning message when called, as the sleep\n * functionality is not supported in the Phaser Box2D JS implementation.\n */\nexport function b2SleepMilliseconds(ms)\n{\n console.warn(\"b2SleepMilliseconds not supported\");\n}\n\n/**\n * @summary Placeholder function for b2Yield functionality\n * @function b2Yield\n * @returns {void}\n * @description\n * This function serves as a placeholder for Box2D's b2Yield functionality, which is not supported\n * in the Phaser Box2D JS implementation. When called, it emits a warning to the console.\n */\nexport function b2Yield()\n{\n console.warn(\"b2Yield not supported\");\n}\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @defgroup id Ids\n * These ids serve as handles to internal Box2D objects.\n * These should be considered opaque data and passed by value.\n * Include this header if you need the id types and not the whole Box2D API.\n * All ids are considered null if initialized to zero.\n *\n * For example in JavaScript:\n *\n * @code{.js}\n * let worldId = {};\n * @endcode\n *\n * This is considered null.\n *\n * @warning Do not use the internals of these ids. They are subject to change. Ids should be treated as opaque objects.\n * @warning You should use ids to access objects in Box2D. Do not access files within the src folder. Such usage is unsupported.\n */\n\n/**\n * @class b2WorldId\n * @summary World id references a world instance. This should be treated as an opaque handle.\n * @property {number} index1 - Index value stored as unsigned 16-bit integer\n * @property {number} revision - Revision value stored as unsigned 16-bit integer\n */\nexport class b2WorldId\n{\n constructor(index = 0, revision = 0)\n {\n this.index1 = index;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2BodyId\n * @summary Body id references a body instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2BodyId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ShapeId\n * @summary Shape id references a shape instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ShapeId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2JointId\n * @summary Joint id references a joint instance. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit world identifier\n * @property {number} revision - 16-bit revision number\n */\nexport class b2JointId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n/**\n * @class b2ChainId\n * @summary Chain id references a chain instances. This should be treated as an opaque handle.\n * @property {number} index1 - Integer index value\n * @property {number} world0 - 16-bit unsigned integer value\n * @property {number} revision - 16-bit unsigned integer value\n */\nexport class b2ChainId\n{\n constructor(index = 0, world = 0, revision = 0)\n {\n this.index1 = index;\n this.world0 = world;\n this.revision = revision;\n }\n}\n\n// Use these to make your identifiers null.\n// You may also use zero initialization to get null.\n// JS conversion NOTE: replace with new call in-situ, make sure c'tor sets all to 0\n// export const b2_nullWorldId = B2_ZERO_INIT; // b2WorldId\n// export const b2_nullBodyId = B2_ZERO_INIT; // b2BodyId\n// export const b2_nullShapeId = B2_ZERO_INIT; // b2ShapeId\n// export const b2_nullJointId = B2_ZERO_INIT; // b2JointId\n// export const b2_nullChainId = B2_ZERO_INIT; // b2ChainId\n\n/**\n * @summary Checks if a contact ID is null/invalid\n * @function B2_IS_NULL\n * @param {Object} id - A contact ID object containing index1 property\n * @returns {boolean} Returns true if the contact ID is null (index1 === 0), false otherwise\n * @description\n * Tests if a contact ID represents a null/invalid contact by checking if its index1\n * property equals 0. In Box2D, an index1 value of 0 indicates a null contact ID.\n */\nexport function B2_IS_NULL(id)\n{\n return id.index1 === 0;\n}\n\n/**\n * @summary Checks if a contact ID is non-null.\n * @function B2_IS_NON_NULL\n * @param {Object} id - A contact ID object containing an index1 property.\n * @returns {boolean} Returns true if the contact ID is non-null (index1 !== 0), false otherwise.\n * @description\n * Tests whether a contact ID represents a valid contact by checking if its index1\n * property is not equal to 0. A zero value for index1 indicates a null contact ID.\n */\nexport function B2_IS_NON_NULL(id)\n{\n return id.index1 !== 0;\n}\n\n/**\n * @summary Compares two ID objects for equality.\n * @function B2_ID_EQUALS\n * @param {Object} id1 - First ID object containing index1, world0, and revision properties.\n * @param {Object} id2 - Second ID object containing index1, world0, and revision properties.\n * @returns {boolean} True if all corresponding properties between id1 and id2 are equal, false otherwise.\n * @description\n * Performs a strict equality comparison between corresponding properties of two ID objects.\n * Checks equality of index1, world0, and revision properties.\n */\nexport function B2_ID_EQUALS(id1, id2)\n{\n return id1.index1 === id2.index1 && id1.world0 === id2.world0 && id1.revision === id2.revision;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\n// Constants\nexport const B2_MAX_POLYGON_VERTICES = 8;\nexport const B2_DEFAULT_CATEGORY_BITS = 0x00000001;\nexport const B2_DEFAULT_MASK_BITS = 0xFFFFFFFF;\n\n// Classes\n\n/**\n * @class b2RayCastInput\n * @summary Low level ray cast input data\n * @property {b2Vec2} origin - Start point of the ray cast\n * @property {b2Vec2} translation - Translation of the ray cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2RayCastInput\n{\n constructor()\n {\n this.origin = null; // new b2Vec2(0,0);\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2ShapeCastInput\n * @summary Low level shape cast input in generic form. This allows casting an arbitrary point cloud wrap with a radius. For example, a circle is a single point with a non-zero radius. A capsule is two points with a non-zero radius. A box is four points with a zero radius.\n * @property {b2Vec2[]} points - A point cloud to cast\n * @property {number} count - The number of points\n * @property {number} radius - The radius around the point cloud\n * @property {b2Vec2} translation - The translation of the shape cast\n * @property {number} maxFraction - The maximum fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastInput\n{\n constructor()\n {\n this.points = []; // Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0, 0));\n this.count = 0;\n this.radius = 0;\n this.translation = null; // new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2CastOutput\n * @summary Low level ray cast or shape-cast output data\n * @property {b2Vec2} normal - The surface normal at the hit point\n * @property {b2Vec2} point - The surface hit point\n * @property {number} fraction - The fraction of the input translation at collision\n * @property {number} iterations - The number of iterations used\n * @property {boolean} hit - Did the cast hit?\n */\nexport class b2CastOutput\n{\n constructor(normal = null, point = null)\n {\n this.normal = normal; // new b2Vec2(0,0);\n this.point = point; // new b2Vec2(0,0);\n this.fraction = 0;\n this.iterations = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2MassData\n * @summary This holds the mass data computed for a shape.\n * @property {number} mass - The mass of the shape, usually in kilograms.\n * @property {b2Vec2} center - The position of the shape's centroid relative to the shape's origin.\n * @property {number} rotationalInertia - The rotational inertia of the shape about the local origin.\n */\nexport class b2MassData\n{\n constructor()\n {\n this.mass = 0;\n this.center = null; // new b2Vec2(0,0);\n this.rotationalInertia = 0;\n }\n}\n\n/**\n * @class b2Circle\n * @summary A solid circle\n * @property {b2Vec2} center - The local center\n * @property {number} radius - The radius\n */\nexport class b2Circle\n{\n constructor(center = null, radius = 0)\n {\n this.center = center;\n\n if (!this.center)\n {\n this.center = new b2Vec2(0,0);\n }\n\n this.radius = radius;\n }\n}\n\n/**\n * @class b2Capsule\n * @summary A solid capsule can be viewed as two semicircles connected by a rectangle.\n * @property {b2Vec2} center1 - Local center of the first semicircle\n * @property {b2Vec2} center2 - Local center of the second semicircle\n * @property {number} radius - The radius of the semicircles\n */\nexport class b2Capsule\n{\n constructor()\n {\n this.center1 = null;\n this.center2 = null;\n this.radius = 0;\n }\n}\n\n/**\n * @class b2Polygon\n * @summary 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_MAX_POLYGON_VERTICES. In most cases you should not need many vertices for a convex polygon.\n * @warning DO NOT fill this out manually, instead use a helper function like b2MakePolygon or b2MakeBox.\n * @property {b2Vec2[]} vertices - The polygon vertices\n * @property {b2Vec2[]} normals - The outward normal vectors of the polygon sides\n * @property {b2Vec2} centroid - The centroid of the polygon\n * @property {number} radius - The external radius for rounded polygons\n * @property {number} count - The number of polygon vertices\n */\nexport class b2Polygon\n{\n constructor(vertices)\n {\n if (vertices > 0)\n {\n this.vertices = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n this.normals = new Array(vertices).fill().map(() => new b2Vec2(0,0));\n }\n else\n {\n this.vertices = [];\n this.normals = [];\n }\n\n this.centroid = null;\n this.radius = 0;\n this.count = 0;\n }\n}\n\n/**\n * @class b2Segment\n * @summary A line segment with two-sided collision\n * @property {b2Vec2} point1 - The first point\n * @property {b2Vec2} point2 - The second point\n */\nexport class b2Segment\n{\n constructor(point1 = null, point2 = null)\n {\n this.point1 = point1;\n this.point2 = point2;\n }\n}\n\nexport class b2ChainSegment\n{\n constructor()\n {\n this.ghost1 = null; // new b2Vec2(0,0);\n this.segment = null; // new b2Segment();\n this.ghost2 = null; // new b2Vec2(0,0);\n this.chainId = 0;\n }\n}\n\n/**\n * @class b2Hull\n * @summary A convex hull. Used to create convex polygons.\n * @warning Do not modify these values directly, instead use b2ComputeHull()\n * @property {b2Vec2[]} points - The final points of the hull\n * @property {number} count - The number of points\n */\nexport class b2Hull\n{\n constructor()\n {\n this.points = []; // new Array(B2_MAX_POLYGON_VERTICES).fill().map(() => new b2Vec2(0,0));\n this.count = 0;\n }\n}\n\n/**\n * @class b2SegmentDistanceResult\n * @summary Result of computing the distance between two line segments\n * @property {b2Vec2} closest1 - The closest point on the first segment\n * @property {b2Vec2} closest2 - The closest point on the second segment\n * @property {number} fraction1 - The barycentric coordinate on the first segment\n * @property {number} fraction2 - The barycentric coordinate on the second segment\n * @property {number} distanceSquared - The squared distance between the closest points\n */\nexport class b2SegmentDistanceResult\n{\n constructor()\n {\n this.closest1 = null; // new b2Vec2(0,0);\n this.closest2 = null; // new b2Vec2(0,0);\n this.fraction1 = 0;\n this.fraction2 = 0;\n this.distanceSquared = 0;\n }\n}\n\n/**\n * @class b2DistanceProxy\n * @summary A distance proxy used by the GJK algorithm. It encapsulates any shape.\n * @property {b2Vec2[]} points - The point cloud\n * @property {number} count - The number of points\n * @property {number} radius - The external radius of the point cloud\n */\nexport class b2DistanceProxy\n{\n constructor(points = [], count = null, radius = 0)\n {\n this.points = points;\n this.count = count;\n this.radius = radius;\n }\n\n clone()\n {\n const points = [];\n\n for (let i = 0, l = this.points.length; i < l; i++)\n {\n points.push(this.points[i]);\n }\n\n return new b2DistanceProxy(points, this.count, this.radius);\n }\n}\n\n/**\n * @class b2DistanceCache\n * @summary Used to warm start b2Distance. Set count to zero on first call or use zero initialization.\n * @property {number} count - The number of stored simplex points\n * @property {number[]} indexA - The cached simplex indices on shape A\n * @property {number[]} indexB - The cached simplex indices on shape B\n */\nexport class b2DistanceCache\n{\n constructor()\n {\n this.count = 0;\n this.indexA = [ 0,0,0 ];\n this.indexB = [ 0,0,0 ];\n \n }\n clone()\n {\n const cache = new b2DistanceCache();\n cache.count = this.count;\n cache.indexA = [ ...this.indexA ];\n cache.indexB = [ ...this.indexB ];\n\n return cache;\n }\n}\n\n// export const b2_emptyDistanceCache = new b2DistanceCache();\n\n/**\n * @class b2DistanceInput\n * @summary Input for b2ShapeDistance\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Transform} transformA - The world transform for shape A\n * @property {b2Transform} transformB - The world transform for shape B\n * @property {boolean} useRadii - Should the proxy radius be considered?\n */\nexport class b2DistanceInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.useRadii = false;\n }\n}\n\n/**\n * @class b2DistanceOutput\n * @summary Output for b2ShapeDistance\n * @property {b2Vec2} pointA - Closest point on shapeA\n * @property {b2Vec2} pointB - Closest point on shapeB\n * @property {number} distance - The final distance, zero if overlapped\n * @property {number} iterations - Number of GJK iterations used\n * @property {number} simplexCount - The number of simplexes stored in the simplex array\n */\nexport class b2DistanceOutput\n{\n constructor()\n {\n this.pointA = new b2Vec2(0,0);\n this.pointB = new b2Vec2(0,0);\n this.distance = 0;\n this.iterations = 0;\n this.simplexCount = 0;\n }\n}\n\n/**\n * @class b2SimplexVertex\n * @summary Simplex vertex for debugging the GJK algorithm\n * @property {b2Vec2} wA - Support point in proxyA\n * @property {b2Vec2} wB - Support point in proxyB\n * @property {b2Vec2} w - wB - wA\n * @property {number} a - Barycentric coordinate for closest point\n * @property {number} indexA - wA index\n * @property {number} indexB - wB index\n */\nexport class b2SimplexVertex\n{\n constructor()\n {\n this.wA = null; // new b2Vec2(0,0);\n this.wB = null; // new b2Vec2(0,0);\n this.w = null; // new b2Vec2(0,0);\n this.a = 0;\n this.indexA = 0;\n this.indexB = 0;\n }\n\n clone()\n {\n const sv = new b2SimplexVertex();\n sv.wA = this.wA.clone();\n sv.wB = this.wB.clone();\n sv.w = this.w.clone();\n sv.a = this.a;\n sv.indexA = this.indexA;\n sv.indexB = this.indexB;\n\n return sv;\n }\n}\n\n/**\n * @class b2Simplex\n * @summary Simplex from the GJK algorithm\n * @property {b2SimplexVertex} v1 - Simplex vertex\n * @property {b2SimplexVertex} v2 - Simplex vertex\n * @property {b2SimplexVertex} v3 - Simplex vertex\n * @property {number} count - Number of valid vertices\n */\nexport class b2Simplex\n{\n constructor()\n {\n this.v1 = new b2SimplexVertex();\n this.v2 = new b2SimplexVertex();\n this.v3 = new b2SimplexVertex();\n this.count = 0;\n }\n}\n\n/**\n * @class b2ShapeCastPairInput\n * @summary Input parameters for b2ShapeCast\n * @property {b2DistanceProxy} proxyA The proxy for shape A\n * @property {b2DistanceProxy} proxyB The proxy for shape B\n * @property {b2Transform} transformA The world transform for shape A\n * @property {b2Transform} transformB The world transform for shape B\n * @property {b2Vec2} translationB The translation of shape B\n * @property {number} maxFraction The fraction of the translation to consider, typically 1\n */\nexport class b2ShapeCastPairInput\n{\n constructor()\n {\n this.proxyA = new b2DistanceProxy();\n this.proxyB = new b2DistanceProxy();\n this.transformA = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.transformB = new b2Transform(new b2Vec2(0,0), new b2Rot(0,0));\n this.translationB = new b2Vec2(0,0);\n this.maxFraction = 0;\n }\n}\n\n/**\n * @class b2Sweep\n * @summary Describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin, which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass position.\n * @property {b2Vec2} localCenter - Local center of mass position\n * @property {b2Vec2} c1 - Starting center of mass world position\n * @property {b2Vec2} c2 - Ending center of mass world position\n * @property {b2Rot} q1 - Starting world rotation\n * @property {b2Rot} q2 - Ending world rotation\n */\nexport class b2Sweep\n{\n constructor(c = null, v1 = null, v2 = null, r1 = null, r2 = null)\n {\n this.localCenter = c;\n this.c1 = v1;\n this.c2 = v2;\n this.q1 = r1;\n this.q2 = r2;\n }\n\n clone()\n {\n return new b2Sweep(this.localCenter.clone(), this.c1.clone(), this.c2.clone(), this.q1.clone(), this.q2.clone());\n }\n}\n\n/**\n * @class b2TOIInput\n * @summary Input parameters for b2TimeOfImpact\n * @property {b2DistanceProxy} proxyA - The proxy for shape A\n * @property {b2DistanceProxy} proxyB - The proxy for shape B\n * @property {b2Sweep} sweepA - The movement of shape A\n * @property {b2Sweep} sweepB - The movement of shape B\n * @property {number} tMax - Defines the sweep interval [0, tMax]\n */\nexport class b2TOIInput\n{\n constructor(proxyA = null, proxyB = null, sweepA = null, sweepB = null, tMax = 0)\n {\n this.proxyA = proxyA; // new b2DistanceProxy();\n this.proxyB = proxyB; // new b2DistanceProxy();\n this.sweepA = sweepA; // new b2Sweep();\n this.sweepB = sweepB; // new b2Sweep();\n this.tMax = tMax;\n }\n\n clone()\n {\n return new b2TOIInput(this.proxyA.clone(), this.proxyB.clone(), this.sweepA.clone(), this.sweepB.clone(), this.tMax);\n }\n}\n\nexport const b2TOIState = {\n b2_toiStateUnknown: 0,\n b2_toiStateFailed: 1,\n b2_toiStateOverlapped: 2,\n b2_toiStateHit: 3,\n b2_toiStateSeparated: 4\n};\n\n/**\n * @class b2TOIOutput\n * @summary Output parameters for b2TimeOfImpact\n * @property {b2TOIState} state - The type of result\n * @property {number} t - The time of the collision\n */\nexport class b2TOIOutput\n{\n constructor()\n {\n this.state = b2TOIState.b2_toiStateUnknown;\n this.t = 0;\n }\n}\n\n/**\n * @class b2ManifoldPoint\n * @summary 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.\n * @property {b2Vec2} point - Location of the contact point in world space. Subject to precision loss at large coordinates. Should only be used for debugging.\n * @property {b2Vec2} anchorA - Location of the contact point relative to bodyA's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {b2Vec2} anchorB - Location of the contact point relative to bodyB's origin in world space. When used internally to the Box2D solver, this is relative to the center of mass.\n * @property {number} separation - The separation of the contact point, negative if penetrating\n * @property {number} normalImpulse - The impulse along the manifold normal vector\n * @property {number} tangentImpulse - The friction impulse\n * @property {number} maxNormalImpulse - The maximum normal impulse applied during sub-stepping\n * @property {number} normalVelocity - Relative normal velocity pre-solve. Used for hit events. If the normal impulse is zero then there was no hit. Negative means shapes are approaching.\n * @property {number} id - Uniquely identifies a contact point between two shapes\n * @property {boolean} persisted - Did this contact point exist the previous step?\n */\nexport class b2ManifoldPoint\n{\n constructor()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n }\n\n clone()\n {\n const clone = new b2ManifoldPoint();\n clone.pointX = this.pointX;\n clone.pointY = this.pointY;\n clone.anchorAX = this.anchorAX;\n clone.anchorAY = this.anchorAY;\n clone.anchorBX = this.anchorBX;\n clone.anchorBY = this.anchorBY;\n clone.separation = this.separation;\n clone.normalImpulse = this.normalImpulse;\n clone.tangentImpulse = this.tangentImpulse;\n clone.maxNormalImpulse = this.maxNormalImpulse;\n clone.normalVelocity = this.normalVelocity;\n clone.id = this.id;\n clone.persisted = this.persisted;\n\n return clone;\n }\n\n clear()\n {\n this.pointX = 0;\n this.pointY = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.separation = 0;\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.normalVelocity = 0;\n this.id = 0;\n this.persisted = false;\n\n return this;\n }\n\n copyTo(mp)\n {\n mp.pointX = this.pointX;\n mp.pointY = this.pointY;\n mp.anchorAX = this.anchorAX;\n mp.anchorAY = this.anchorAY;\n mp.anchorBX = this.anchorBX;\n mp.anchorBY = this.anchorBY;\n mp.separation = this.separation;\n mp.normalImpulse = this.normalImpulse;\n mp.tangentImpulse = this.tangentImpulse;\n mp.maxNormalImpulse = this.maxNormalImpulse;\n mp.normalVelocity = this.normalVelocity;\n mp.id = this.id;\n mp.persisted = this.persisted;\n }\n}\n\n/**\n * @class b2Manifold\n * @summary A contact manifold describes the contact points between colliding shapes\n * @property {b2ManifoldPoint[]} points - The manifold points, up to two are possible in 2D\n * @property {b2Vec2} normal - The unit normal vector in world space, points from shape A to bodyB\n * @property {number} pointCount - The number of contacts points, will be 0, 1, or 2\n */\nexport class b2Manifold\n{\n constructor(p1 = new b2ManifoldPoint(), p2 = new b2ManifoldPoint())\n {\n this.points = [ p1, p2 ];\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n }\n\n clone()\n {\n const clone = new b2Manifold();\n\n this.copyTo(clone);\n\n return clone;\n }\n\n clear()\n {\n if (this.points[0])\n {\n this.points[0].clear();\n }\n\n if (this.points[1])\n {\n this.points[1].clear();\n }\n\n this.normalX = this.normalY = 0;\n this.pointCount = 0;\n\n return this;\n }\n\n copyTo(manifold)\n {\n this.points[0].copyTo(manifold.points[0]);\n this.points[1].copyTo(manifold.points[1]);\n manifold.normalX = this.normalX;\n manifold.normalY = this.normalY;\n manifold.pointCount = this.pointCount;\n }\n}\n\n/**\n * @class b2TreeNode\n * @summary A node in the dynamic tree. This is private data placed here for performance reasons.\n * @property {b2AABB} aabb - The node bounding box\n * @property {number} categoryBits - Category bits for collision filtering\n * @property {number} parent - The node parent index (allocated node)\n * @property {number} next - The node freelist next index (free node)\n * @property {number} child1 - Child 1 index (internal node)\n * @property {number} child2 - Child 2 index (internal node)\n * @property {number} userData - User data (leaf node)\n * @property {number} height - Node height\n * @property {number} flags - Node flags\n */\nexport class b2TreeNode\n{\n constructor()\n {\n this.aabb = null;\n this.categoryBits = 0;\n\n // NOTE: removed the C union of parent and next\n this.parent_next = B2_NULL_INDEX;\n this.child1 = B2_NULL_INDEX;\n this.child2 = B2_NULL_INDEX;\n this.userData = 0;\n this.height = -1;\n this.enlarged = false;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace Table\n */\n\n// use a map instead of an object: Map can use bigint as a key where object will convert it to a string first\n// WARNING: map has property 'size' instead of the C original 'count' and does not have 'capacity'\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport function b2CreateSet()\n{\n return new Map();\n}\n\nexport function b2DestroySet(set)\n{\n set.clear();\n}\n\nexport function b2ClearSet(set)\n{\n set.clear();\n}\n\nexport function b2ContainsKey(set, key)\n{\n return set.has(key);\n}\n\nexport function b2AddKey(set, key)\n{\n if (set.has(key))\n {\n return true;\n }\n set.set(key, 1);\n\n return false;\n}\n\nexport function b2RemoveKey(set, key)\n{\n return set.delete(key);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const B2_SHAPE_PAIR_KEY = (K1, K2) => K1 < K2 ? BigInt(K1) << 32n | BigInt(K2) : BigInt(K2) << 32n | BigInt(K1);\n\nexport {\n\n // b2SetItem,\n b2CreateSet,\n b2DestroySet,\n b2ClearSet,\n b2AddKey,\n b2RemoveKey,\n b2ContainsKey\n} from '../table_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n/**\n * @namespace StackAllocator\n*/\n\n// TODO: remove this utterly in the future, it's just an array wrapper in JS\n\nexport class b2StackAllocator\n{\n constructor()\n {\n this.data = null;\n this.entries = null;\n \n }\n}\n\nclass b2StackEntry\n{\n constructor()\n {\n this.data = null;\n this.name = null;\n this.size = 0;\n \n }\n}\n\nexport function b2CreateStackAllocator(capacity)\n{\n const allocator = new b2StackAllocator();\n allocator.data = [];\n allocator.entries = [];\n\n return allocator;\n}\n\nexport function b2DestroyStackAllocator(allocator)\n{\n allocator.data = null;\n allocator.entries = null;\n}\n\nexport function b2AllocateStackItem(alloc, size, name, ctor = null)\n{\n console.assert(size >= 0);\n const entry = new b2StackEntry();\n entry.size = size;\n entry.name = name;\n entry.data = [];\n\n for (let i = 0; i < size; i++)\n {\n if (ctor)\n { entry.data.push(ctor()); }\n else\n { entry.data.push(null); }\n }\n alloc.entries.push(entry);\n\n return entry.data;\n}\n\nexport function b2FreeStackItem(alloc, mem)\n{\n const entryCount = alloc.entries.length;\n console.assert(entryCount > 0);\n const entry = alloc.entries[entryCount - 1];\n console.assert(entry.data == mem);\n console.assert(entry.size >= 0);\n alloc.entries.pop();\n}\n\nexport function b2GrowStack(alloc)\n{\n}\n\nexport function b2GetStackCapacity(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n\nexport function b2GetStackAllocation(alloc)\n{\n return alloc.entries.length;\n}\n\nexport function b2GetMaxStackAllocation(alloc)\n{\n return Number.MAX_SAFE_INTEGER;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\n\n/**\n * @namespace Allocate\n*/\n\n// In JS we don't need to allocate space for the array or grow it because it can't become 'full'\n// however the initCallback is useful for ensuring that class object constructors get called\n\nexport function b2Alloc(size, initCallback = null)\n{\n const ptr = [];\n\n if (initCallback)\n {\n for (let i = 0; i < size; i++)\n { ptr[i] = initCallback(); }\n }\n\n return ptr;\n}\n\nexport function b2Grow(mem, newSize, initCallback = null)\n{\n const oldSize = mem.length;\n\n if (initCallback)\n {\n for (let i = oldSize; i < newSize; i++)\n { mem[i] = initCallback(); }\n }\n\n return mem;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyDef, b2BodyType, b2ChainDef, b2Filter, b2QueryFilter, b2ShapeDef, b2WorldDef } from './include/types_h.js';\nimport { b2Rot, b2Vec2 } from './include/math_functions_h.js';\n\nimport { b2_lengthUnitsPerMeter } from './include/core_h.js';\n\n/**\n * @namespace Types\n */\n\nexport const b2Validation = false;\n\nexport const b2Assert = function(condition, message, forceCheck = false)\n{\n if (b2Validation || forceCheck)\n {\n if (!condition)\n {\n const error = new Error(message);\n error.stack = error.stack.split('\\n').slice(1)[0];\n console.assert(false, error);\n }\n }\n};\n\n/**\n * Creates a default world definition with pre-configured physics simulation parameters.\n * @function b2DefaultWorldDef\n * @returns {b2WorldDef} A world definition object with the following properties:\n * - gravity: {b2Vec2} Set to (0, -10)\n * - hitEventThreshold: {number} Set to 1 meter\n * - restitutionThreshold: {number} Set to 10 meters\n * - contactPushoutVelocity: {number} Set to 5 meters\n * - contactHertz: {number} Set to 30\n * - contactDampingRatio: {number} Set to 10\n * - jointHertz: {number} Set to 60\n * - jointDampingRatio: {number} Set to 5\n * - maximumLinearVelocity: {number} Set to 400 meters\n * - enableSleep: {boolean} Set to true\n * - enableContinuous: {boolean} Set to true\n * @description\n * Initializes a new b2WorldDef with default values suitable for standard physics simulations.\n * All distance-based values are scaled by b2_lengthUnitsPerMeter2.\n */\nexport function b2DefaultWorldDef()\n{\n const def = new b2WorldDef();\n def.gravity = new b2Vec2(0.0, -10.0);\n def.hitEventThreshold = 1.0 * b2_lengthUnitsPerMeter;\n def.restitutionThreshold = 10.0 * b2_lengthUnitsPerMeter;\n def.contactPushoutVelocity = 5.0 * b2_lengthUnitsPerMeter;\n def.contactHertz = 30.0;\n def.contactDampingRatio = 10.0;\n def.jointHertz = 60.0;\n def.jointDampingRatio = 5.0;\n def.maximumLinearVelocity = 400.0 * b2_lengthUnitsPerMeter;\n def.enableSleep = true;\n def.enableContinuous = true;\n\n return def;\n}\n\n/**\n * Creates a new b2BodyDef with default values.\n * @function b2DefaultBodyDef\n * @returns {b2BodyDef} A body definition object with the following default properties:\n * - type: b2_staticBody\n * - position: (0,0)\n * - rotation: (cos=1, sin=0)\n * - linearVelocity: (0,0)\n * - angularVelocity: 0\n * - linearDamping: 0\n * - angularDamping: 0\n * - gravityScale: 1\n * - sleepThreshold: 0.05 * b2_lengthUnitsPerMeter2\n * - userData: null\n * - enableSleep: true\n * - isAwake: true\n * - fixedRotation: false\n * - isBullet: false\n * - isEnabled: true\n * - updateBodyMass: true\n * - allowFastRotation: false\n */\nexport function b2DefaultBodyDef()\n{\n const def = new b2BodyDef();\n def.type = b2BodyType.b2_staticBody;\n def.position = new b2Vec2(0, 0);\n def.rotation = new b2Rot(1, 0);\n def.linearVelocity = new b2Vec2(0, 0);\n def.angularVelocity = 0;\n def.linearDamping = 0;\n def.angularDamping = 0;\n def.gravityScale = 1.0;\n def.sleepThreshold = 0.05 * b2_lengthUnitsPerMeter;\n def.userData = null;\n def.enableSleep = true;\n def.isAwake = true;\n def.fixedRotation = false;\n def.isBullet = false;\n def.isEnabled = true;\n def.updateBodyMass = true;\n def.allowFastRotation = false;\n\n return def;\n}\n\n/**\n * @summary Creates a default collision filter with standard values.\n * @function b2DefaultFilter\n * @returns {b2Filter} A filter object with categoryBits=1, maskBits=4294967295 (0xFFFFFFFF), and groupIndex=0\n * @description\n * Creates and returns a new b2Filter object initialized with default values for collision filtering.\n * The categoryBits determine what collision category this object belongs to,\n * the maskBits determine what categories this object can collide with,\n * and the groupIndex determines collision groups (negative values mean never collide,\n * positive values mean always collide with same group).\n */\nexport function b2DefaultFilter()\n{\n const filter = new b2Filter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n filter.groupIndex = 0;\n\n return filter;\n}\n\n/**\n * Creates a default query filter with standard settings.\n * @function b2DefaultQueryFilter\n * @returns {b2QueryFilter} A query filter object with categoryBits set to 1 and\n * maskBits set to 4294967295 (0xFFFFFFFF).\n * @description\n * This function instantiates a new b2QueryFilter with default collision filtering\n * settings. The categoryBits value of 1 represents the default category, while\n * the maskBits value of 4294967295 allows collision with all categories.\n */\nexport function b2DefaultQueryFilter()\n{\n const filter = new b2QueryFilter();\n filter.categoryBits = 0x00000001;\n filter.maskBits = 0xffffffff;\n\n return filter;\n}\n\n/**\n * Creates a default shape definition with standard physics properties.\n * @function b2DefaultShapeDef\n * @returns {b2ShapeDef} A shape definition object with the following default values:\n * - friction: 0.6\n * - density: 1\n * - restitution: 0.1\n * - filter: default collision filter\n * - enableSensorEvents: true\n * - enableContactEvents: true\n * @description\n * This function initializes a new b2ShapeDef object with commonly used physics\n * properties. The shape definition can be used to create various types of\n * physics shapes in Box2D.\n */\nexport function b2DefaultShapeDef()\n{\n const def = new b2ShapeDef();\n def.friction = 0.6;\n def.density = 1.0;\n def.restitution = 0.1;\n def.filter = b2DefaultFilter();\n def.enableSensorEvents = true;\n def.enableContactEvents = true;\n\n return def;\n}\n\n/**\n * Creates a new b2ChainDef with default values.\n * @function b2DefaultChainDef\n * @returns {b2ChainDef} A chain definition object with:\n * - friction set to 0.6\n * - default filter settings\n * - all other properties at their default values\n * @description\n * Initializes a new chain definition with common default values.\n * The chain shape represents a series of connected line segments.\n */\nexport function b2DefaultChainDef()\n{\n const def = new b2ChainDef();\n def.friction = 0.6;\n def.filter = b2DefaultFilter();\n\n return def;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Rot, b2Vec2 } from './math_functions_h.js';\n\nexport {\n\n // debugging\n b2Validation,\n\n b2DefaultWorldDef, b2DefaultBodyDef, b2DefaultFilter, b2DefaultQueryFilter, b2DefaultShapeDef, b2DefaultChainDef,\n} from '../types_c.js';\n\nexport const b2BodyType = {\n b2_staticBody: 0,\n b2_kinematicBody: 1,\n b2_dynamicBody: 2,\n b2_bodyTypeCount: 3\n};\n\nexport const b2ShapeType = {\n b2_circleShape: 0,\n b2_capsuleShape: 1,\n b2_segmentShape: 2,\n b2_polygonShape: 3,\n b2_chainSegmentShape: 4,\n b2_shapeTypeCount: 5\n};\n\nexport const b2JointType = {\n b2_distanceJoint: 0,\n b2_motorJoint: 1,\n b2_mouseJoint: 2,\n b2_prismaticJoint: 3,\n b2_revoluteJoint: 4,\n b2_weldJoint: 5,\n b2_wheelJoint: 6,\n b2_unknown: -1\n};\n\n/**\n * Result from b2World_RayCastClosest\n * @class b2RayResult\n * @property {b2ShapeId} shapeId - The shape that was hit\n * @property {b2Vec2} point - The hit point\n * @property {b2Vec2} normal - The hit normal\n * @property {number} fraction - The hit fraction along the ray\n * @property {number} nodeVisits - Number of tree nodes visited\n * @property {number} leafVisits - Number of tree leaves visited\n * @property {boolean} hit - Whether the ray hit anything\n */\nexport class b2RayResult\n{\n constructor()\n {\n this.shapeId = null;\n this.point = new b2Vec2(0, 0);\n this.normal = new b2Vec2(0, 0);\n this.fraction = 0;\n this.hit = false;\n }\n}\n\n/**\n * @class b2WorldDef\n * @summary World definition used to create a simulation world. Must be initialized using b2DefaultWorldDef().\n * @property {b2Vec2} gravity - Gravity vector. Box2D has no up-vector defined.\n * @property {number} restitutionThreshold - Restitution velocity threshold, usually in m/s. Collisions above this speed have restitution applied (will bounce).\n * @property {number} contactPushoutVelocity - This parameter controls how fast overlap is resolved and has units of meters per second\n * @property {number} hitEventThreshold - Threshold velocity for hit events. Usually meters per second.\n * @property {number} contactHertz - Contact stiffness. Cycles per second.\n * @property {number} contactDampingRatio - Contact bounciness. Non-dimensional.\n * @property {number} jointHertz - Joint stiffness. Cycles per second.\n * @property {number} jointDampingRatio - Joint bounciness. Non-dimensional.\n * @property {number} maximumLinearVelocity - Maximum linear velocity. Usually meters per second.\n * @property {b2MixingRule} frictionMixingRule - Mixing rule for friction. Default is b2_mixGeometricMean.\n * @property {b2MixingRule} restitutionMixingRule - Mixing rule for restitution. Default is b2_mixMaximum.\n * @property {boolean} enableSleep - Can bodies go to sleep to improve performance\n * @property {boolean} enableContinuous - Enable continuous collision\n * @property {number} workerCount - Number of workers to use with the provided task system.\n * @property {Function} enqueueTask - Function to spawn tasks\n * @property {Function} finishTask - Function to finish a task\n * @property {*} userTaskContext - User context that is provided to enqueueTask and finishTask\n * @property {*} userData - User data\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WorldDef\n{\n constructor()\n {\n this.gravity = new b2Vec2(0, 0);\n this.restitutionThreshold = 0;\n this.contactPushoutVelocity = 0;\n this.hitEventThreshold = 0;\n this.contactHertz = 0;\n this.contactDampingRatio = 0;\n this.jointHertz = 0;\n this.jointDampingRatio = 0;\n this.maximumLinearVelocity = 0;\n this.enableSleep = false;\n this.enableContinuous = true;\n this.workerCount = 0;\n\n // this.userTaskContext = null;\n }\n}\n\n/**\n * @class b2BodyDef\n * @summary Definition used to construct a rigid body\n * @property {b2BodyType} type - The body type: static, kinematic, or dynamic\n * @property {b2Vec2} position - The initial world position of the body\n * @property {b2Rot} rotation - The initial world rotation of the body\n * @property {b2Vec2} linearVelocity - The initial linear velocity in meters per second\n * @property {number} angularVelocity - The initial angular velocity in radians per second\n * @property {number} linearDamping - Linear damping to reduce linear velocity\n * @property {number} angularDamping - Angular damping to reduce angular velocity\n * @property {number} gravityScale - Scale factor applied to gravity for this body\n * @property {number} sleepThreshold - Sleep velocity threshold, default 0.05 m/s\n * @property {*} userData - Application specific body data\n * @property {boolean} enableSleep - Whether this body can fall asleep\n * @property {boolean} isAwake - Whether body starts awake or sleeping\n * @property {boolean} fixedRotation - Whether to prevent rotation\n * @property {boolean} isBullet - Whether to use continuous collision detection\n * @property {boolean} isEnabled - Whether body can move and collide\n * @property {boolean} allowFastRotation - Whether to bypass rotation speed limits\n * @property {number} internalValue - Internal validation flag\n */\nexport class b2BodyDef\n{\n constructor()\n {\n this.type = b2BodyType.b2_staticBody;\n this.position = new b2Vec2(0, 0);\n this.rotation = new b2Rot(1, 0);\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.sleepThreshold = 0;\n this.userData = null;\n this.enableSleep = false;\n this.isAwake = false;\n this.fixedRotation = false;\n this.isBullet = false;\n this.isEnabled = false;\n this.updateBodyMass = false;\n this.allowFastRotation = false;\n }\n}\n\n/**\n * @class b2ShapeDef\n * @summary Used to create a shape. This is a temporary object used to bundle shape creation parameters.\n * You may use the same shape definition to create multiple shapes.\n * Must be initialized using b2DefaultShapeDef().\n * @property {*} userData - Use this to store application specific shape data\n * @property {number} friction - The Coulomb (dry) friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (bounce) usually in the range [0,1]\n * @property {number} density - The density, usually in kg/m^2\n * @property {b2Filter} filter - Collision filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isSensor - A sensor shape generates overlap events but never generates a collision response\n * @property {boolean} enableSensorEvents - Enable sensor events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableContactEvents - Enable contact events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enableHitEvents - Enable hit events for this shape. Only applies to kinematic and dynamic bodies\n * @property {boolean} enablePreSolveEvents - Enable pre-solve contact events for this shape. Only applies to dynamic bodies\n * @property {boolean} invokeContactCreation - Override static body behavior to force contact creation\n * @property {boolean} updateBodyMass - Should the body update mass properties when shape is created\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET\n */\nexport class b2ShapeDef\n{\n constructor()\n {\n this.userData = null;\n this.friction = 0;\n this.restitution = 0;\n this.density = 0;\n this.filter = new b2Filter();\n this.customColor = b2HexColor.b2_colorAqua; // .b2_colorAliceBlue;\n\n // / Sensors do not collide with other sensors and do not have continuous collision.\n // / Instead use a ray or shape cast for those scenarios.\n this.isSensor = false;\n\n // / Enable sensor events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableSensorEvents = false;\n\n // / Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableContactEvents = false;\n\n // / Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.\n this.enableHitEvents = false;\n\n // / Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive\n // /\tand must be carefully handled due to threading. Ignored for sensors.\n // / PJB NOTE: threading concerns do not apply to the JS translation.\n this.enablePreSolveEvents = false;\n\n // / Normally shapes on static bodies don't invoke contact creation when they are added to the world. This overrides\n // /\tthat behavior and causes contact creation. This significantly slows down static body creation which can be important\n // /\twhen there are many static shapes.\n // / This is implicitly always true for sensors.\n this.forceContactCreation = false;\n }\n}\n\n/**\n * @class b2ChainDef\n * @summary Definition for creating a chain of line segments. Designed for static bodies with one-sided collision detection.\n * @property {void} userData - Use this to store application specific shape data\n * @property {b2Vec2[]} points - Array of at least 4 points defining the chain segments\n * @property {number} count - The point count, must be 4 or more\n * @property {number} friction - The friction coefficient, usually in the range [0,1]\n * @property {number} restitution - The restitution (elasticity) usually in the range [0,1]\n * @property {b2Filter} filter - Contact filtering data\n * @property {number} customColor - Custom debug draw color\n * @property {boolean} isLoop - Indicates a closed chain formed by connecting first and last points\n * @property {number} internalValue - Used internally to detect valid definition. DO NOT SET\n */\nexport class b2ChainDef\n{\n constructor()\n {\n this.userData = null;\n this.points = null;\n this.count = 0;\n this.friction = 0;\n this.restitution = 0;\n this.filter = new b2Filter();\n this.isLoop = false;\n }\n}\n\n/**\n * @class b2DistanceJointDef\n * @summary Distance joint definition that connects two bodies with a specified distance between anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} length - The rest length of this joint. Clamped to a stable minimum value.\n * @property {boolean} enableSpring - Enable the distance constraint to behave like a spring. If false then the distance joint will be rigid, overriding the limit and motor.\n * @property {number} hertz - The spring linear stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring linear damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} minLength - Minimum length. Clamped to a stable minimum value.\n * @property {number} maxLength - Maximum length. Must be greater than or equal to the minimum length.\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, usually in newtons\n * @property {number} motorSpeed - The desired motor speed, usually in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n * @description 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.\n */\nexport class b2DistanceJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.length = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.minLength = 0;\n this.maxLength = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MotorJointDef\n * @summary A motor joint controls relative motion between two bodies, typically used to control a dynamic body relative to ground\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} linearOffset - Position of bodyB minus the position of bodyA, in bodyA's frame\n * @property {number} angularOffset - The bodyB angle minus bodyA angle in radians\n * @property {number} maxForce - The maximum motor force in newtons\n * @property {number} maxTorque - The maximum motor torque in newton-meters\n * @property {number} correctionFactor - Position correction factor in the range [0,1]\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MotorJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.linearOffset = new b2Vec2(0, 0);\n this.angularOffset = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2MouseJointDef\n * @summary Definition for a mouse joint that makes a point on a body track a world point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} target - The initial target point in world space\n * @property {number} hertz - Stiffness in hertz\n * @property {number} dampingRatio - Damping ratio, non-dimensional\n * @property {number} maxForce - Maximum force, typically in newtons\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2MouseJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.target = new b2Vec2(0, 0);\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2PrismaticJointDef\n * @summary Prismatic joint definition that constrains motion along a defined axis\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {number} referenceAngle - The constrained angle between the bodies: bodyB_angle - bodyA_angle\n * @property {boolean} enableSpring - Enable a linear spring along the prismatic joint axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint motor\n * @property {number} maxMotorForce - The maximum motor force, typically in newtons\n * @property {number} motorSpeed - The desired motor speed, typically in meters per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2PrismaticJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2RevoluteJointDef\n * @summary Revolute joint definition that specifies how two bodies are joined at an anchor point\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {boolean} enableSpring - Enable a rotational spring on the revolute hinge axis\n * @property {number} hertz - The spring stiffness Hertz, cycles per second\n * @property {number} dampingRatio - The spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - A flag to enable joint limits\n * @property {number} lowerAngle - The lower angle for the joint limit in radians\n * @property {number} upperAngle - The upper angle for the joint limit in radians\n * @property {boolean} enableMotor - A flag to enable the joint motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {number} drawSize - Scale the debug draw\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2RevoluteJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.drawSize = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WeldJointDef\n * @summary Weld joint definition that connects two bodies rigidly with optional spring properties\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {number} referenceAngle - The bodyB angle minus bodyA angle in the reference state (radians)\n * @property {number} linearHertz - Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} angularHertz - Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.\n * @property {number} linearDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {number} angularDampingRatio - Linear damping ratio, non-dimensional. Use 1 for critical damping.\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WeldJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.angularHertz = 0;\n this.linearDampingRatio = 0;\n this.angularDampingRatio = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2WheelJointDef\n * @summary Wheel joint definition that defines a line of motion using an axis and anchor points\n * @property {b2BodyId} bodyIdA - The first attached body\n * @property {b2BodyId} bodyIdB - The second attached body\n * @property {b2Vec2} localAnchorA - The local anchor point relative to bodyA's origin\n * @property {b2Vec2} localAnchorB - The local anchor point relative to bodyB's origin\n * @property {b2Vec2} localAxisA - The local translation unit axis in bodyA\n * @property {boolean} enableSpring - Enable a linear spring along the local axis\n * @property {number} hertz - Spring stiffness in Hertz\n * @property {number} dampingRatio - Spring damping ratio, non-dimensional\n * @property {boolean} enableLimit - Enable/disable the joint linear limit\n * @property {number} lowerTranslation - The lower translation limit\n * @property {number} upperTranslation - The upper translation limit\n * @property {boolean} enableMotor - Enable/disable the joint rotational motor\n * @property {number} maxMotorTorque - The maximum motor torque, typically in newton-meters\n * @property {number} motorSpeed - The desired motor speed in radians per second\n * @property {boolean} collideConnected - Set this flag to true if the attached bodies should collide\n * @property {*} userData - User data pointer\n * @property {number} internalValue - Used internally to detect a valid definition. DO NOT SET.\n */\nexport class b2WheelJointDef\n{\n constructor()\n {\n this.bodyIdA = null;\n this.bodyIdB = null;\n this.localAnchorA = new b2Vec2(0, 0);\n this.localAnchorB = new b2Vec2(0, 0);\n this.localAxisA = new b2Vec2(0, 0);\n this.enableSpring = false;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.enableLimit = false;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.enableMotor = false;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.collideConnected = false;\n this.userData = null;\n }\n}\n\n/**\n * @class b2SensorBeginTouchEvent\n * @summary A begin touch event is generated when a shape starts to overlap a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that began touching the sensor shape\n */\nexport class b2SensorBeginTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEndTouchEvent\n * @summary An end touch event is generated when a shape stops overlapping a sensor shape.\n * @property {b2ShapeId} sensorShapeId - The id of the sensor shape\n * @property {b2ShapeId} visitorShapeId - The id of the dynamic shape that stopped touching the sensor shape\n */\nexport class b2SensorEndTouchEvent\n{\n constructor()\n {\n this.sensorShapeId = null;\n this.visitorShapeId = null;\n }\n}\n\n/**\n * @class b2SensorEvents\n * @summary Buffered sensor events from the Box2D world available after time step completion\n * @property {b2SensorBeginTouchEvent[]} beginEvents - Array of sensor begin touch events\n * @property {b2SensorEndTouchEvent[]} endEvents - Array of sensor end touch events\n * @property {number} beginCount - The number of begin touch events\n * @property {number} endCount - The number of end touch events\n */\nexport class b2SensorEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n }\n}\n\n/**\n * @class b2ContactBeginTouchEvent\n * @summary A begin touch event is generated when two shapes begin touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Manifold} manifold - The initial contact manifold\n */\nexport class b2ContactBeginTouchEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\n/**\n * @class b2ContactEndTouchEvent\n * @summary An end touch event is generated when two shapes stop touching.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n */\nexport class b2ContactEndTouchEvent\n{\n constructor(a = null, b = null)\n {\n this.shapeIdA = a;\n this.shapeIdB = b;\n }\n}\n\n/**\n * @class b2ContactHitEvent\n * @summary A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.\n * @property {b2ShapeId} shapeIdA - Id of the first shape\n * @property {b2ShapeId} shapeIdB - Id of the second shape\n * @property {b2Vec2} point - Point where the shapes hit\n * @property {b2Vec2} normal - Normal vector pointing from shape A to shape B\n * @property {number} approachSpeed - The speed the shapes are approaching. Always positive. Typically in meters per second.\n */\nexport class b2ContactHitEvent\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.pointX = 0;\n this.pointY = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.approachSpeed = 0;\n }\n}\n\n/**\n * @class b2ContactEvents\n * @summary Contact events buffered in the Box2D world available after time step completion\n * @property {b2ContactBeginTouchEvent[]} beginEvents - Array of begin touch events\n * @property {b2ContactEndTouchEvent[]} endEvents - Array of end touch events\n * @property {b2ContactHitEvent[]} hitEvents - Array of hit events\n * @property {number} beginCount - Number of begin touch events\n * @property {number} endCount - Number of end touch events\n * @property {number} hitCount - Number of hit events\n */\nexport class b2ContactEvents\n{\n constructor()\n {\n this.beginEvents = null;\n this.endEvents = null;\n this.hitEvents = null;\n this.beginCount = 0;\n this.endCount = 0;\n this.hitCount = 0;\n }\n}\n\n/**\n * @class b2BodyMoveEvent\n * @summary Body move events triggered during physics simulation. Provides efficient batch updates for moved bodies and sleep state changes.\n * @property {b2Transform} transform - The new transform of the moved body\n * @property {b2BodyId} bodyId - The identifier of the moved body\n * @property {void} userData - User data associated with the body\n * @property {boolean} fellAsleep - Indicates if the body transitioned to sleep state\n */\nexport class b2BodyMoveEvent\n{\n constructor()\n {\n this.transform = null;\n this.bodyId = null;\n this.userData = null;\n this.fellAsleep = false;\n }\n}\n\n/**\n * @class b2BodyEvents\n * @summary Body events buffered in the Box2D world, available after time step completion\n * @property {b2BodyMoveEvent[]} moveEvents - Array of move events\n * @property {number} moveCount - Number of move events\n */\nexport class b2BodyEvents\n{\n constructor()\n {\n this.moveEvents = null;\n this.moveCount = 0;\n }\n}\n\n/**\n * @class b2ContactData\n * @summary The contact data for two shapes. By convention the manifold normal points from shape A to shape B.\n * @see b2Shape_GetContactData()\n * @see b2Body_GetContactData()\n * @property {b2ShapeId} shapeIdA - The identifier for the first shape\n * @property {b2ShapeId} shapeIdB - The identifier for the second shape\n * @property {b2Manifold} manifold - The contact manifold between the shapes\n */\nexport class b2ContactData\n{\n constructor()\n {\n this.shapeIdA = null;\n this.shapeIdB = null;\n this.manifold = null;\n }\n}\n\nexport const b2HexColor = {\n b2_colorAliceBlue: 0xf0f8ff,\n b2_colorAntiqueWhite: 0xfaebd7,\n b2_colorAqua: 0x00ffff,\n b2_colorAquamarine: 0x7fffd4,\n b2_colorAzure: 0xf0ffff,\n b2_colorBeige: 0xf5f5dc,\n b2_colorBisque: 0xffe4c4,\n b2_colorBlack: 0x000001, // non-zero!\n b2_colorBlanchedAlmond: 0xffebcd,\n b2_colorBlue: 0x0000ff,\n b2_colorBlueViolet: 0x8a2be2,\n b2_colorBrown: 0xa52a2a,\n b2_colorBurlywood: 0xdeb887,\n b2_colorCadetBlue: 0x5f9ea0,\n b2_colorChartreuse: 0x7fff00,\n b2_colorChocolate: 0xd2691e,\n b2_colorCoral: 0xff7f50,\n b2_colorCornflowerBlue: 0x6495ed,\n b2_colorCornsilk: 0xfff8dc,\n b2_colorCrimson: 0xdc143c,\n b2_colorCyan: 0x00ffff,\n b2_colorDarkBlue: 0x00008b,\n b2_colorDarkCyan: 0x008b8b,\n b2_colorDarkGoldenrod: 0xb8860b,\n b2_colorDarkGray: 0xa9a9a9,\n b2_colorDarkGreen: 0x006400,\n b2_colorDarkKhaki: 0xbdb76b,\n b2_colorDarkMagenta: 0x8b008b,\n b2_colorDarkOliveGreen: 0x556b2f,\n b2_colorDarkOrange: 0xff8c00,\n b2_colorDarkOrchid: 0x9932cc,\n b2_colorDarkRed: 0x8b0000,\n b2_colorDarkSalmon: 0xe9967a,\n b2_colorDarkSeaGreen: 0x8fbc8f,\n b2_colorDarkSlateBlue: 0x483d8b,\n b2_colorDarkSlateGray: 0x2f4f4f,\n b2_colorDarkTurquoise: 0x00ced1,\n b2_colorDarkViolet: 0x9400d3,\n b2_colorDeepPink: 0xff1493,\n b2_colorDeepSkyBlue: 0x00bfff,\n b2_colorDimGray: 0x696969,\n b2_colorDodgerBlue: 0x1e90ff,\n b2_colorFirebrick: 0xb22222,\n b2_colorFloralWhite: 0xfffaf0,\n b2_colorForestGreen: 0x228b22,\n b2_colorFuchsia: 0xff00ff,\n b2_colorGainsboro: 0xdcdcdc,\n b2_colorGhostWhite: 0xf8f8ff,\n b2_colorGold: 0xffd700,\n b2_colorGoldenrod: 0xdaa520,\n b2_colorGray: 0xbebebe,\n b2_colorGray1: 0x1a1a1a,\n b2_colorGray2: 0x333333,\n b2_colorGray3: 0x4d4d4d,\n b2_colorGray4: 0x666666,\n b2_colorGray5: 0x7f7f7f,\n b2_colorGray6: 0x999999,\n b2_colorGray7: 0xb3b3b3,\n b2_colorGray8: 0xcccccc,\n b2_colorGray9: 0xe5e5e5,\n b2_colorGreen: 0x00ff00,\n b2_colorGreenYellow: 0xadff2f,\n b2_colorHoneydew: 0xf0fff0,\n b2_colorHotPink: 0xff69b4,\n b2_colorIndianRed: 0xcd5c5c,\n b2_colorIndigo: 0x4b0082,\n b2_colorIvory: 0xfffff0,\n b2_colorKhaki: 0xf0e68c,\n b2_colorLavender: 0xe6e6fa,\n b2_colorLavenderBlush: 0xfff0f5,\n b2_colorLawnGreen: 0x7cfc00,\n b2_colorLemonChiffon: 0xfffacd,\n b2_colorLightBlue: 0xadd8e6,\n b2_colorLightCoral: 0xf08080,\n b2_colorLightCyan: 0xe0ffff,\n b2_colorLightGoldenrod: 0xeedd82,\n b2_colorLightGoldenrodYellow: 0xfafad2,\n b2_colorLightGray: 0xd3d3d3,\n b2_colorLightGreen: 0x90ee90,\n b2_colorLightPink: 0xffb6c1,\n b2_colorLightSalmon: 0xffa07a,\n b2_colorLightSeaGreen: 0x20b2aa,\n b2_colorLightSkyBlue: 0x87cefa,\n b2_colorLightSlateBlue: 0x8470ff,\n b2_colorLightSlateGray: 0x778899,\n b2_colorLightSteelBlue: 0xb0c4de,\n b2_colorLightYellow: 0xffffe0,\n b2_colorLime: 0x00ff00,\n b2_colorLimeGreen: 0x32cd32,\n b2_colorLinen: 0xfaf0e6,\n b2_colorMagenta: 0xff00ff,\n b2_colorMaroon: 0xb03060,\n b2_colorMediumAquamarine: 0x66cdaa,\n b2_colorMediumBlue: 0x0000cd,\n b2_colorMediumOrchid: 0xba55d3,\n b2_colorMediumPurple: 0x9370db,\n b2_colorMediumSeaGreen: 0x3cb371,\n b2_colorMediumSlateBlue: 0x7b68ee,\n b2_colorMediumSpringGreen: 0x00fa9a,\n b2_colorMediumTurquoise: 0x48d1cc,\n b2_colorMediumVioletRed: 0xc71585,\n b2_colorMidnightBlue: 0x191970,\n b2_colorMintCream: 0xf5fffa,\n b2_colorMistyRose: 0xffe4e1,\n b2_colorMoccasin: 0xffe4b5,\n b2_colorNavajoWhite: 0xffdead,\n b2_colorNavy: 0x000080,\n b2_colorNavyBlue: 0x000080,\n b2_colorOldLace: 0xfdf5e6,\n b2_colorOlive: 0x808000,\n b2_colorOliveDrab: 0x6b8e23,\n b2_colorOrange: 0xffa500,\n b2_colorOrangeRed: 0xff4500,\n b2_colorOrchid: 0xda70d6,\n b2_colorPaleGoldenrod: 0xeee8aa,\n b2_colorPaleGreen: 0x98fb98,\n b2_colorPaleTurquoise: 0xafeeee,\n b2_colorPaleVioletRed: 0xdb7093,\n b2_colorPapayaWhip: 0xffefd5,\n b2_colorPeachPuff: 0xffdab9,\n b2_colorPeru: 0xcd853f,\n b2_colorPink: 0xffc0cb,\n b2_colorPlum: 0xdda0dd,\n b2_colorPowderBlue: 0xb0e0e6,\n b2_colorPurple: 0xa020f0,\n b2_colorRebeccaPurple: 0x663399,\n b2_colorRed: 0xff0000,\n b2_colorRosyBrown: 0xbc8f8f,\n b2_colorRoyalBlue: 0x4169e1,\n b2_colorSaddleBrown: 0x8b4513,\n b2_colorSalmon: 0xfa8072,\n b2_colorSandyBrown: 0xf4a460,\n b2_colorSeaGreen: 0x2e8b57,\n b2_colorSeashell: 0xfff5ee,\n b2_colorSienna: 0xa0522d,\n b2_colorSilver: 0xc0c0c0,\n b2_colorSkyBlue: 0x87ceeb,\n b2_colorSlateBlue: 0x6a5acd,\n b2_colorSlateGray: 0x708090,\n b2_colorSnow: 0xfffafa,\n b2_colorSpringGreen: 0x00ff7f,\n b2_colorSteelBlue: 0x4682b4,\n b2_colorTan: 0xd2b48c,\n b2_colorTeal: 0x008080,\n b2_colorThistle: 0xd8bfd8,\n b2_colorTomato: 0xff6347,\n b2_colorTurquoise: 0x40e0d0,\n b2_colorViolet: 0xee82ee,\n b2_colorVioletRed: 0xd02090,\n b2_colorWheat: 0xf5deb3,\n b2_colorWhite: 0xffffff,\n b2_colorWhiteSmoke: 0xf5f5f5,\n b2_colorYellow: 0xffff00,\n b2_colorYellowGreen: 0x9acd32,\n b2_colorBox2DRed: 0xdc3132,\n b2_colorBox2DBlue: 0x30aebf,\n b2_colorBox2DGreen: 0x8cc924,\n b2_colorBox2DYellow: 0xffee8c\n};\n\n/**\n * @class b2DebugDraw\n * @summary Callbacks and options for debug rendering of a Box2D world\n * @property {function(b2Vec2, string, *): void} DrawString - Draw a string\n * @property {b2AABB} drawingBounds - Bounds to use if restricting drawing to a rectangular region\n * @property {boolean} useDrawingBounds - Option to restrict drawing to a rectangular region. May suffer from unstable depth sorting\n * @property {boolean} drawShapes - Option to draw shapes\n * @property {boolean} drawJoints - Option to draw joints\n * @property {boolean} drawJointExtras - Option to draw additional information for joints\n * @property {boolean} drawAABBs - Option to draw the bounding boxes for shapes\n * @property {boolean} drawMass - Option to draw the mass and center of mass of dynamic bodies\n * @property {boolean} drawContacts - Option to draw contact points\n * @property {boolean} drawGraphColors - Option to visualize the graph coloring used for contacts and joints\n * @property {boolean} drawContactNormals - Option to draw contact normals\n * @property {boolean} drawContactImpulses - Option to draw contact normal impulses\n * @property {boolean} drawFrictionImpulses - Option to draw contact friction impulses\n * @property {*} context - User context that is passed as an argument to drawing callback functions\n */\nexport class b2DebugDraw\n{\n constructor()\n {\n this.DrawPolygon = null;\n this.DrawImagePolygon = null;\n this.DrawSolidPolygon = null;\n this.DrawCircle = null;\n this.DrawImageCircle = null;\n this.DrawSolidCircle = null;\n this.DrawImageCapsule = null;\n this.DrawSolidCapsule = null;\n this.DrawSegment = null;\n this.DrawTransform = null;\n this.DrawPoint = null;\n this.DrawString = null;\n this.SetPosition = null;\n this.drawingBounds = new b2AABB();\n this.useDrawingBounds = false; // PJB: not fully implemented in debug_draw.js\n this.positionOffset = new b2Vec2();\n this.drawShapes = true;\n this.drawJoints = false;\n this.drawAABBs = false;\n this.drawMass = false;\n this.drawContacts = false;\n this.drawGraphColors = false;\n this.drawContactNormals = false;\n this.drawContactImpulses = false;\n this.drawFrictionImpulses = false;\n this.context = null;\n }\n}\n\n/**\n * @class b2Filter\n * @summary Used to filter collision on shapes. Affects shape-vs-shape collision and shape-versus-query collision.\n * @property {number} categoryBits - The collision category bits. Normally you would just set one bit.\n * The category bits should represent your application object types.\n * @property {number} maskBits - The collision mask bits. States the categories that this shape would\n * accept for collision.\n * @property {number} groupIndex - Collision groups allow a certain group of objects to never collide\n * (negative) or always collide (positive). Zero has no effect. Non-zero group filtering always wins\n * against the mask bits.\n */\nexport class b2Filter\n{\n constructor()\n {\n this.categoryBits = 0x0001;\n this.maskBits = 0xFFFF;\n this.groupIndex = 0;\n }\n}\n\n/**\n * @class b2QueryFilter\n * @summary Filter used to control collision detection between queries and shapes\n * @property {number} categoryBits - The collision category bits of this query. Normally you would just set one bit.\n * @property {number} maskBits - The collision mask bits. This states the shape categories that this query would accept for collision.\n */\nexport class b2QueryFilter\n{\n constructor()\n {\n this.categoryBits = 0xFFFF;\n this.maskBits = 0xFFFF;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Validation } from './include/types_h.js';\n\n/**\n * @namespace IDPool\n */\n\nexport class b2IdPool\n{\n constructor(name)\n {\n this.name = name;\n this.freeArray = [];\n this.nextIndex = 0;\n }\n}\n\nexport function b2GetIdCapacity(pool)\n{\n return pool.nextIndex;\n}\n\nexport function b2CreateIdPool(name = 'pool')\n{\n return new b2IdPool(name);\n}\n\nexport function b2DestroyIdPool(pool)\n{\n pool.freeArray = null;\n pool.nextIndex = 0;\n}\n\nexport function b2AllocId(pool)\n{\n if (pool.freeArray.length > 0)\n {\n return pool.freeArray.pop();\n }\n\n const id = pool.nextIndex;\n pool.nextIndex++;\n\n return id;\n}\n\nexport function b2FreeId(pool, id)\n{\n if (id === pool.nextIndex - 1)\n {\n pool.nextIndex--;\n\n return;\n }\n\n pool.freeArray.push(id);\n}\n\nexport function b2GetIdCount(pool)\n{\n return pool.nextIndex - pool.freeArray.length;\n}\n\nexport function b2ValidateFreeId(pool, id)\n{\n if (!b2Validation) { return; }\n\n const freeCount = pool.freeArray.length;\n\n if (id == pool.nextIndex)\n { return; }\n \n for (let i = 0; i < freeCount; ++i)\n {\n if (pool.freeArray[i] == id)\n {\n return;\n }\n }\n\n console.warn(\"pool \" + pool.constructor.name + \" has no free Id \" + id);\n console.warn(pool.freeArray);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_MAX_POLYGON_VERTICES,\n b2CastOutput,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2SegmentDistanceResult,\n b2Simplex,\n b2SimplexVertex,\n b2Sweep,\n b2TOIOutput,\n b2TOIState\n} from './include/collision_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2Distance,\n b2Dot,\n b2InvMulTransforms,\n b2InvRotateVector,\n b2IsNormalized,\n b2LeftPerp,\n b2Length,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2NormalizeRot,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\n\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Distance\n */\n\n/**\n * @function b2GetSweepTransform\n * @summary Computes an interpolated transform at a specified time during a sweep motion.\n * @param {b2Sweep} sweep - A sweep object containing initial (c1, q1) and final (c2, q2)\n * positions and rotations, along with a local center offset.\n * @param {number} time - Interpolation factor between 0 and 1, where 0 represents the initial\n * state and 1 represents the final state.\n * @returns {b2Transform} A transform object containing the interpolated position (p) and\n * rotation (q) at the specified time.\n * @description\n * Calculates an intermediate transform by linearly interpolating between two states\n * defined in a sweep motion. The resulting transform accounts for both translation\n * and rotation, adjusted by the local center offset.\n */\nexport function b2GetSweepTransform(sweep, time)\n{\n const xf = new b2Transform();\n xf.p = b2Add(b2MulSV(1.0 - time, sweep.c1), b2MulSV(time, sweep.c2));\n\n const q = new b2Rot((1.0 - time) * sweep.q1.c + time * sweep.q2.c,\n (1.0 - time) * sweep.q1.s + time * sweep.q2.s);\n\n xf.q = b2NormalizeRot(q);\n \n xf.p = b2Sub(xf.p, b2RotateVector(xf.q, sweep.localCenter));\n\n return xf;\n}\n\n/**\n * @function b2SegmentDistance\n * @description\n * Calculates the minimum distance between two line segments defined by their endpoints.\n * @param {number} p1X - X coordinate of the first point of segment 1\n * @param {number} p1Y - Y coordinate of the first point of segment 1\n * @param {number} q1X - X coordinate of the second point of segment 1\n * @param {number} q1Y - Y coordinate of the second point of segment 1\n * @param {number} p2X - X coordinate of the first point of segment 2\n * @param {number} p2Y - Y coordinate of the first point of segment 2\n * @param {number} q2X - X coordinate of the second point of segment 2\n * @param {number} q2Y - Y coordinate of the second point of segment 2\n * @returns {b2SegmentDistanceResult} An object containing:\n * - fraction1: {number} Parameter along segment 1 for closest point (0-1)\n * - fraction2: {number} Parameter along segment 2 for closest point (0-1)\n * - distanceSquared: {number} Square of the minimum distance between segments\n */\nconst sdResult = new b2SegmentDistanceResult();\n\nexport function b2SegmentDistance(p1X, p1Y, q1X, q1Y, p2X, p2Y, q2X, q2Y)\n{\n let fraction1 = 0;\n let fraction2 = 0;\n\n const d1X = q1X - p1X;\n const d1Y = q1Y - p1Y;\n const d2X = q2X - p2X;\n const d2Y = q2Y - p2Y;\n const rX = p1X - p2X;\n const rY = p1Y - p2Y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n const rd2 = rX * d2X + rY * d2Y;\n const rd1 = rX * d1X + rY * d1Y;\n\n if (dd1 < epsSqr || dd2 < epsSqr)\n {\n if (dd1 >= epsSqr)\n {\n fraction1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n fraction2 = 0.0;\n }\n else if (dd2 >= epsSqr)\n {\n fraction1 = 0.0;\n fraction2 = b2ClampFloat(rd2 / dd2, 0.0, 1.0);\n }\n }\n else\n {\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n fraction1 = f1;\n fraction2 = f2;\n }\n\n const closest1X = p1X + fraction1 * d1X;\n const closest1Y = p1Y + fraction1 * d1Y;\n const closest2X = p2X + fraction2 * d2X;\n const closest2Y = p2Y + fraction2 * d2Y;\n \n const dX = closest1X - closest2X;\n const dY = closest1Y - closest2Y;\n const distanceSquared = dX * dX + dY * dY;\n\n sdResult.closest1 = sdResult.closest2 = null;\n sdResult.fraction1 = fraction1;\n sdResult.fraction2 = fraction2;\n sdResult.distanceSquared = distanceSquared;\n\n return sdResult;\n}\n\n/**\n * @function b2MakeProxy\n * @summary Creates a distance proxy from a set of vertices\n * @param {b2Vec2[]} vertices - Array of 2D vectors representing the vertices\n * @param {number} count - Number of vertices to process (max B2_MAX_POLYGON_VERTICES)\n * @param {number} radius - Radius value for the proxy\n * @returns {b2DistanceProxy} A new distance proxy containing the processed vertices\n * @throws {Error} Throws assertion error if count exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2MakeProxy(vertices, count, radius)\n{\n console.assert(count <= B2_MAX_POLYGON_VERTICES);\n \n count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n \n const proxy = new b2DistanceProxy();\n proxy.points = [];\n proxy.count = count;\n proxy.radius = radius;\n\n for (let i = 0; i < count; ++i)\n {\n proxy.points[i] = vertices[i].clone();\n }\n\n return proxy;\n}\n\nfunction b2Weight2(a1, w1, a2, w2)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x, a1 * w1.y + a2 * w2.y);\n}\n\nfunction b2Weight3(a1, w1, a2, w2, a3, w3)\n{\n return new b2Vec2(a1 * w1.x + a2 * w2.x + a3 * w3.x, a1 * w1.y + a2 * w2.y + a3 * w3.y);\n}\n\nfunction b2FindSupport(proxy, direction)\n{\n let bestIndex = 0;\n let bestValue = b2Dot(proxy.points[0], direction);\n\n for (let i = 1; i < proxy.count; ++i)\n {\n const value = b2Dot(proxy.points[i], direction);\n\n if (value > bestValue)\n {\n bestIndex = i;\n bestValue = value;\n }\n }\n\n return bestIndex;\n}\n\nfunction b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB)\n{\n const s = new b2Simplex();\n s.count = cache.count;\n\n const vertices = [ s.v1, s.v2, s.v3 ];\n\n for (let i = 0; i < s.count; ++i)\n {\n const v = vertices[i];\n v.indexA = cache.indexA[i];\n v.indexB = cache.indexB[i];\n const wALocal = proxyA.points[v.indexA];\n const wBLocal = proxyB.points[v.indexB];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = -1.0;\n }\n\n if (s.count === 0)\n {\n const v = vertices[0];\n v.indexA = 0;\n v.indexB = 0;\n const wALocal = proxyA.points[0];\n const wBLocal = proxyB.points[0];\n v.wA = b2TransformPoint(transformA, wALocal);\n v.wB = b2TransformPoint(transformB, wBLocal);\n v.w = b2Sub(v.wB, v.wA);\n v.a = 1.0;\n s.count = 1;\n }\n\n return s;\n}\n\nfunction b2MakeSimplexCache(cache, simplex)\n{\n cache.count = simplex.count;\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n for (let i = 0; i < simplex.count; ++i)\n {\n cache.indexA[i] = vertices[i].indexA;\n cache.indexB[i] = vertices[i].indexB;\n }\n}\n\nfunction b2ComputeSimplexSearchDirection(simplex)\n{\n switch (simplex.count)\n {\n case 1:\n return b2Neg(simplex.v1.w);\n\n case 2:\n const e12 = b2Sub(simplex.v2.w, simplex.v1.w);\n const sgn = b2Cross(e12, b2Neg(simplex.v1.w));\n\n if (sgn > 0.0)\n {\n return b2LeftPerp(e12);\n }\n else\n {\n return b2RightPerp(e12);\n }\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexClosestPoint(s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n\n case 1:\n return s.v1.w;\n\n case 2:\n return b2Weight2(s.v1.a, s.v1.w, s.v2.a, s.v2.w);\n\n case 3:\n return new b2Vec2(0, 0);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\nfunction b2ComputeSimplexWitnessPoints(a, b, s)\n{\n switch (s.count)\n {\n case 0:\n console.assert(false);\n\n break;\n\n case 1:\n a.x = s.v1.wA.x;\n a.y = s.v1.wA.y;\n b.x = s.v1.wB.x;\n b.y = s.v1.wB.y;\n\n break;\n\n case 2:\n a.x = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).x;\n a.y = b2Weight2(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA).y;\n b.x = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).x;\n b.y = b2Weight2(s.v1.a, s.v1.wB, s.v2.a, s.v2.wB).y;\n\n break;\n\n case 3:\n a.x = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).x;\n a.y = b2Weight3(s.v1.a, s.v1.wA, s.v2.a, s.v2.wA, s.v3.a, s.v3.wA).y;\n b.x = a.x;\n b.y = a.y;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n}\n\nfunction b2SolveSimplex2(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const e12 = b2Sub(w2, w1);\n\n const d12_2 = -b2Dot(w1, e12);\n\n if (d12_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n const d12_1 = b2Dot(w2, e12);\n\n if (d12_1 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2;\n\n return;\n }\n\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n}\n\nfunction b2SolveSimplex3(s)\n{\n const w1 = s.v1.w;\n const w2 = s.v2.w;\n const w3 = s.v3.w;\n\n const e12 = b2Sub(w2, w1);\n const w1e12 = b2Dot(w1, e12);\n const w2e12 = b2Dot(w2, e12);\n const d12_1 = w2e12;\n const d12_2 = -w1e12;\n\n const e13 = b2Sub(w3, w1);\n const w1e13 = b2Dot(w1, e13);\n const w3e13 = b2Dot(w3, e13);\n const d13_1 = w3e13;\n const d13_2 = -w1e13;\n\n const e23 = b2Sub(w3, w2);\n const w2e23 = b2Dot(w2, e23);\n const w3e23 = b2Dot(w3, e23);\n const d23_1 = w3e23;\n const d23_2 = -w2e23;\n\n const n123 = b2Cross(e12, e13);\n\n const d123_1 = n123 * b2Cross(w2, w3);\n const d123_2 = n123 * b2Cross(w3, w1);\n const d123_3 = n123 * b2Cross(w1, w2);\n\n if (d12_2 <= 0.0 && d13_2 <= 0.0)\n {\n s.v1.a = 1.0;\n s.count = 1;\n\n return;\n }\n\n if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0)\n {\n const inv_d12 = 1.0 / (d12_1 + d12_2);\n s.v1.a = d12_1 * inv_d12;\n s.v2.a = d12_2 * inv_d12;\n s.count = 2;\n\n return;\n }\n\n if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0)\n {\n const inv_d13 = 1.0 / (d13_1 + d13_2);\n s.v1.a = d13_1 * inv_d13;\n s.v3.a = d13_2 * inv_d13;\n s.count = 2;\n s.v2 = s.v3.clone();\n\n return;\n }\n\n if (d12_1 <= 0.0 && d23_2 <= 0.0)\n {\n s.v2.a = 1.0;\n s.count = 1;\n s.v1 = s.v2.clone();\n\n return;\n }\n\n if (d13_1 <= 0.0 && d23_1 <= 0.0)\n {\n s.v3.a = 1.0;\n s.count = 1;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0)\n {\n const inv_d23 = 1.0 / (d23_1 + d23_2);\n s.v2.a = d23_1 * inv_d23;\n s.v3.a = d23_2 * inv_d23;\n s.count = 2;\n s.v1 = s.v3.clone();\n\n return;\n }\n\n const inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);\n s.v1.a = d123_1 * inv_d123;\n s.v2.a = d123_2 * inv_d123;\n s.v3.a = d123_3 * inv_d123;\n s.count = 3;\n}\n\nconst p0 = new b2Vec2();\n\n/**\n * @function b2ShapeDistance\n * @description\n * Computes the distance between two convex shapes using the GJK (Gilbert-Johnson-Keerthi) algorithm.\n * @param {b2DistanceCache} cache - Cache object to store and retrieve simplex data between calls\n * @param {b2DistanceInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - transformA: Transform for first shape\n * - transformB: Transform for second shape\n * - useRadii: Boolean flag for including shape radii in calculation\n * @param {b2Simplex[]} simplexes - Optional array to store simplex history\n * @param {number} simplexCapacity - Maximum number of simplexes to store\n * @returns {b2DistanceOutput} Output containing:\n * - pointA: Closest point on shape A\n * - pointB: Closest point on shape B\n * - distance: Distance between the shapes\n * - iterations: Number of iterations performed\n * - simplexCount: Number of simplexes stored\n */\nexport function b2ShapeDistance(cache, input, simplexes, simplexCapacity)\n{\n const output = new b2DistanceOutput();\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const transformA = input.transformA;\n const transformB = input.transformB;\n\n const simplex = b2MakeSimplexFromCache(cache, proxyA, transformA, proxyB, transformB);\n\n let simplexIndex = 0;\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n const k_maxIters = 20;\n\n const saveA = [ 0, 0, 0 ];\n const saveB = [ 0, 0, 0 ];\n\n console.assert(simplex.v2 !== simplex.v3);\n\n let iter = 0;\n\n while (iter < k_maxIters)\n {\n const saveCount = simplex.count;\n\n for (let i = 0; i < saveCount; ++i)\n {\n saveA[i] = vertices[i].indexA;\n saveB[i] = vertices[i].indexB;\n }\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n\n if (simplex.count === 3)\n {\n break;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n const d = b2ComputeSimplexSearchDirection(simplex);\n\n if (b2Dot(d, d) < eps * eps)\n {\n break;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = b2FindSupport(proxyA, b2InvRotateVector(transformA.q, b2Neg(d)));\n vertex.wA = b2TransformPoint(transformA, proxyA.points[vertex.indexA]);\n vertex.indexB = b2FindSupport(proxyB, b2InvRotateVector(transformB.q, d));\n vertex.wB = b2TransformPoint(transformB, proxyB.points[vertex.indexB]);\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n\n ++iter;\n\n let duplicate = false;\n\n for (let i = 0; i < saveCount; ++i)\n {\n if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i])\n {\n duplicate = true;\n\n break;\n }\n }\n\n if (duplicate)\n {\n break;\n }\n\n ++simplex.count;\n }\n\n if (simplexes !== null && simplexIndex < simplexCapacity)\n {\n simplexes[simplexIndex] = simplex;\n simplexIndex += 1;\n }\n\n b2ComputeSimplexWitnessPoints(output.pointA, output.pointB, simplex);\n output.distance = b2Distance(output.pointA, output.pointB);\n output.iterations = iter;\n output.simplexCount = simplexIndex;\n\n b2MakeSimplexCache(cache, simplex);\n\n if (input.useRadii)\n {\n if (output.distance < eps)\n {\n p0.x = 0.5 * (output.pointA.x + output.pointB.x);\n p0.y = 0.5 * (output.pointA.y + output.pointB.y);\n output.pointA.x = p0.x;\n output.pointA.y = p0.y;\n output.pointB.x = p0.x;\n output.pointB.y = p0.y;\n output.distance = 0.0;\n }\n else\n {\n const rA = proxyA.radius;\n const rB = proxyB.radius;\n output.distance = Math.max(0.0, output.distance - rA - rB);\n const normal = b2Normalize(b2Sub(output.pointB, output.pointA));\n const offsetAX = rA * normal.x;\n const offsetAY = rA * normal.y;\n const offsetBX = rB * normal.x;\n const offsetBY = rB * normal.y;\n output.pointA.x += offsetAX;\n output.pointA.y += offsetAY;\n output.pointB.x -= offsetBX;\n output.pointB.y -= offsetBY;\n }\n }\n\n return output;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2ShapeCast\n * @summary Performs a shape cast between two convex shapes to detect collision.\n * @param {b2ShapeCastPairInput} input - Contains:\n * proxyA - First shape proxy\n * proxyB - Second shape proxy\n * transformA - Transform of first shape\n * transformB - Transform of second shape\n * translationB - Translation vector for second shape\n * maxFraction - Maximum fraction of motion to check\n * @returns {b2CastOutput} Contains:\n * fraction - Time of impact fraction [0,maxFraction]\n * point - Point of impact\n * normal - Surface normal at impact\n * iterations - Number of iterations used\n * hit - Whether a collision was detected\n * @description\n * Uses an iterative algorithm to determine if and when two convex shapes will collide\n * during a linear motion. Shape B is translated while shape A remains stationary.\n * The algorithm uses support points and simplexes to determine the closest points\n * between the shapes.\n */\nexport function b2ShapeCast(input)\n{\n const output = new b2CastOutput(rayNormal, rayPoint);\n output.fraction = input.maxFraction;\n\n const proxyA = input.proxyA;\n\n const xfA = input.transformA;\n const xfB = input.transformB;\n const xf = b2InvMulTransforms(xfA, xfB);\n\n const proxyB = new b2DistanceProxy();\n proxyB.count = input.proxyB.count;\n proxyB.radius = input.proxyB.radius;\n proxyB.points = [];\n\n for (let i = 0; i < proxyB.count; ++i)\n {\n proxyB.points[i] = b2TransformPoint(xf, input.proxyB.points[i]);\n }\n\n const radius = proxyA.radius + proxyB.radius;\n\n const r = b2RotateVector(xf.q, input.translationB);\n let lambda = 0.0;\n const maxFraction = input.maxFraction;\n\n const simplex = new b2Simplex();\n simplex.count = 0;\n simplex.v1 = new b2SimplexVertex();\n simplex.v2 = new b2SimplexVertex();\n simplex.v3 = new b2SimplexVertex();\n\n const vertices = [ simplex.v1, simplex.v2, simplex.v3 ];\n\n let indexA = b2FindSupport(proxyA, b2Neg(r));\n let wA = proxyA.points[indexA];\n let indexB = b2FindSupport(proxyB, r);\n let wB = proxyB.points[indexB];\n let v = b2Sub(wA, wB);\n\n const linearSlop = 0.005;\n const sigma = Math.max(linearSlop, radius - linearSlop);\n\n const k_maxIters = 20;\n let iter = 0;\n\n while (iter < k_maxIters && b2Length(v) > sigma + 0.5 * linearSlop)\n {\n console.assert(simplex.count < 3);\n\n output.iterations += 1;\n\n indexA = b2FindSupport(proxyA, b2Neg(v));\n wA = proxyA.points[indexA];\n indexB = b2FindSupport(proxyB, v);\n wB = proxyB.points[indexB];\n const p = b2Sub(wA, wB);\n\n v = b2Normalize(v);\n\n const vp = b2Dot(v, p);\n const vr = b2Dot(v, r);\n\n if (vp - sigma > lambda * vr)\n {\n if (vr <= 0.0)\n {\n return output;\n }\n\n lambda = (vp - sigma) / vr;\n\n if (lambda > maxFraction)\n {\n return output;\n }\n\n simplex.count = 0;\n }\n\n const vertex = vertices[simplex.count];\n vertex.indexA = indexB;\n vertex.wA = new b2Vec2(wB.x + lambda * r.x, wB.y + lambda * r.y);\n vertex.indexB = indexA;\n vertex.wB = wA.clone();\n vertex.w = b2Sub(vertex.wB, vertex.wA);\n vertex.a = 1.0;\n simplex.count += 1;\n\n switch (simplex.count)\n {\n case 1:\n break;\n\n case 2:\n b2SolveSimplex2(simplex);\n\n break;\n\n case 3:\n b2SolveSimplex3(simplex);\n\n break;\n\n default:\n console.assert(false);\n }\n\n if (simplex.count === 3)\n {\n return output;\n }\n\n v = b2ComputeSimplexClosestPoint(simplex);\n\n ++iter;\n }\n\n if (iter === 0 || lambda === 0.0)\n {\n return output;\n }\n\n const pointA = new b2Vec2();\n const pointB = new b2Vec2();\n b2ComputeSimplexWitnessPoints(pointB, pointA, simplex);\n\n const n = b2Normalize(b2Neg(v));\n const point = new b2Vec2(pointA.x + proxyA.radius * n.x, pointA.y + proxyA.radius * n.y);\n\n output.point = b2TransformPoint(xfA, point);\n output.normal = b2RotateVector(xfA.q, n);\n output.fraction = lambda;\n output.iterations = iter;\n output.hit = true;\n\n return output;\n}\n\n// #define B2_TOI_DEBUG 0\n\n// Warning: writing to these globals significantly slows multithreading performance\n/*\n#if B2_TOI_DEBUG\nfloat b2_toiTime, b2_toiMaxTime;\nint b2_toiCalls, b2_toiIters, b2_toiMaxIters;\nint b2_toiRootIters, b2_toiMaxRootIters;\n#endif\n*/\n\nconst b2SeparationType = {\n b2_pointsType: 0,\n b2_faceAType: 1,\n b2_faceBType: 2\n};\n\nclass b2SeparationFunction\n{\n constructor()\n {\n this.proxyA = null;\n this.proxyB = null;\n this.sweepA = null;\n this.sweepB = null;\n this.localPoint = new b2Vec2();\n this.axis = new b2Vec2();\n this.type = 0;\n }\n}\n\nexport function b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1)\n{\n const f = new b2SeparationFunction();\n f.proxyA = proxyA;\n f.proxyB = proxyB;\n const count = cache.count;\n console.assert(0 < count && count < 3);\n\n f.sweepA = new b2Sweep();\n Object.assign(f.sweepA, sweepA);\n f.sweepB = new b2Sweep();\n Object.assign(f.sweepB, sweepB);\n f.localPoint = new b2Vec2();\n f.axis = new b2Vec2();\n f.type = 0;\n\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n if (count === 1)\n {\n f.type = b2SeparationType.b2_pointsType;\n const localPointA = proxyA.points[cache.indexA[0]];\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n f.axis = b2Normalize(b2Sub(pointB, pointA));\n f.localPoint = new b2Vec2();\n\n return f;\n }\n\n if (cache.indexA[0] === cache.indexA[1])\n {\n // Two points on B and one on A.\n f.type = b2SeparationType.b2_faceBType;\n const localPointB1 = proxyB.points[cache.indexB[0]];\n const localPointB2 = proxyB.points[cache.indexB[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointB2, localPointB1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfB.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointB1.x + localPointB2.x), 0.5 * (localPointB1.y + localPointB2.y));\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const localPointA = proxyA.points[cache.indexA[0]];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const s = b2Dot(b2Sub(pointA, pointB), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n }\n\n // Two points on A and one or two points on B.\n f.type = b2SeparationType.b2_faceAType;\n const localPointA1 = proxyA.points[cache.indexA[0]];\n const localPointA2 = proxyA.points[cache.indexA[1]];\n\n f.axis = b2CrossVS(b2Sub(localPointA2, localPointA1), 1.0);\n f.axis = b2Normalize(f.axis);\n const normal = b2RotateVector(xfA.q, f.axis);\n\n f.localPoint = new b2Vec2(0.5 * (localPointA1.x + localPointA2.x), 0.5 * (localPointA1.y + localPointA2.y));\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const localPointB = proxyB.points[cache.indexB[0]];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const s = b2Dot(b2Sub(pointB, pointA), normal);\n\n if (s < 0.0)\n {\n f.axis = b2Neg(f.axis);\n }\n\n return f;\n}\n\nclass MinSeparationReturn\n{\n constructor(indexA, indexB, separation)\n {\n this.indexA = indexA;\n this.indexB = indexB;\n this.separation = separation;\n \n }\n}\n\nexport function b2FindMinSeparation(f, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const axisA = b2InvRotateVector(xfA.q, f.axis);\n const axisB = b2InvRotateVector(xfB.q, b2Neg(f.axis));\n\n const indexA = b2FindSupport(f.proxyA, axisA);\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n\n const axisB = b2InvRotateVector(xfB.q, b2Neg(normal));\n\n const indexA = -1;\n const indexB = b2FindSupport(f.proxyB, axisB);\n\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n\n const axisA = b2InvRotateVector(xfA.q, b2Neg(normal));\n\n const indexB = -1;\n const indexA = b2FindSupport(f.proxyA, axisA);\n\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return new MinSeparationReturn(indexA, indexB, separation);\n }\n\n default:\n console.assert(false);\n\n return new MinSeparationReturn(-1, -1, 0.0);\n }\n}\n\nexport function b2EvaluateSeparation(f, indexA, indexB, t)\n{\n const xfA = b2GetSweepTransform(f.sweepA, t);\n const xfB = b2GetSweepTransform(f.sweepB, t);\n\n switch (f.type)\n {\n case b2SeparationType.b2_pointsType:\n {\n const localPointA = f.proxyA.points[indexA];\n const localPointB = f.proxyB.points[indexB];\n const pointA = b2TransformPoint(xfA, localPointA);\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), f.axis);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceAType:\n {\n const normal = b2RotateVector(xfA.q, f.axis);\n const pointA = b2TransformPoint(xfA, f.localPoint);\n const localPointB = f.proxyB.points[indexB];\n const pointB = b2TransformPoint(xfB, localPointB);\n const separation = b2Dot(b2Sub(pointB, pointA), normal);\n\n return separation;\n }\n\n case b2SeparationType.b2_faceBType:\n {\n const normal = b2RotateVector(xfB.q, f.axis);\n const pointB = b2TransformPoint(xfB, f.localPoint);\n const localPointA = f.proxyA.points[indexA];\n const pointA = b2TransformPoint(xfA, localPointA);\n const separation = b2Dot(b2Sub(pointA, pointB), normal);\n\n return separation;\n }\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\n/**\n * @function b2TimeOfImpact\n * @summary Computes the time of impact between two moving shapes. CCD is handled via the local separating axis method. This seeks progression by computing the largest time at which separation is maintained.\n * @param {b2TOIInput} input - Input parameters containing:\n * - proxyA: First shape proxy\n * - proxyB: Second shape proxy\n * - sweepA: Motion sweep for first shape\n * - sweepB: Motion sweep for second shape\n * - tMax: Maximum time interval\n * @returns {b2TOIOutput} Output containing:\n * - state: The termination state (Unknown, Failed, Overlapped, Hit, Separated)\n * - t: Time of impact (between 0 and tMax)\n * @description\n * Computes when two moving shapes first collide during their motion sweeps.\n * Uses conservative advancement and binary search to find the first time of impact\n * or determine that no impact occurs during the time interval.\n * @throws {Error} Throws assertion error if input sweeps are not normalized\n */\nexport function b2TimeOfImpact(input)\n{\n const output = new b2TOIOutput();\n output.state = b2TOIState.b2_toiStateUnknown;\n output.t = input.tMax;\n\n const proxyA = input.proxyA;\n const proxyB = input.proxyB;\n\n const sweepA = input.sweepA;\n const sweepB = input.sweepB;\n console.assert( b2IsNormalized( sweepA.q1 ) && b2IsNormalized( sweepA.q2 ), `sweepA not normalized q1:${sweepA.q1.s*sweepA.q1.s+sweepA.q1.c*sweepA.q1.c} q2:${sweepA.q2.s*sweepA.q2.s+sweepA.q2.c*sweepA.q2.c}` );\n console.assert( b2IsNormalized( sweepB.q1 ) && b2IsNormalized( sweepB.q2 ), `sweepB not normalized q1:${sweepB.q1.s*sweepB.q1.s+sweepB.q1.c*sweepB.q1.c} q2:${sweepB.q2.s*sweepB.q2.s+sweepB.q2.c*sweepB.q2.c}` );\n\n const tMax = input.tMax;\n\n const totalRadius = proxyA.radius + proxyB.radius;\n const target = Math.max(b2_linearSlop, totalRadius - b2_linearSlop);\n const tolerance = 0.25 * b2_linearSlop;\n console.assert( target > tolerance );\n\n let t1 = 0.0;\n const k_maxIterations = 20;\n let iter = 0;\n\n // Prepare input for distance query.\n const cache = new b2DistanceCache();\n const distanceInput = new b2DistanceInput();\n distanceInput.proxyA = input.proxyA;\n distanceInput.proxyB = input.proxyB;\n distanceInput.useRadii = false;\n\n // The outer loop progressively attempts to compute new separating axes.\n // This loop terminates when an axis is repeated (no progress is made).\n for (;;)\n {\n const xfA = b2GetSweepTransform(sweepA, t1);\n const xfB = b2GetSweepTransform(sweepB, t1);\n\n // Get the distance between shapes. We can also use the results\n // to get a separating axis.\n distanceInput.transformA = xfA;\n distanceInput.transformB = xfB;\n const distanceOutput = b2ShapeDistance(cache, distanceInput, null, 0);\n\n // If the shapes are overlapped, we give up on continuous collision.\n if (distanceOutput.distance <= 0.0)\n {\n // Failure!\n // console.warn(\"SAT gives up on CCD \" + distanceOutput.distance);\n output.state = b2TOIState.b2_toiStateOverlapped;\n output.t = 0.0;\n\n break;\n }\n\n if (distanceOutput.distance < target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n\n break;\n }\n\n // Initialize the separating axis.\n const fcn = b2MakeSeparationFunction(cache, proxyA, sweepA, proxyB, sweepB, t1);\n\n // Compute the TOI on the separating axis. We do this by successively\n // resolving the deepest point. This loop is bounded by the number of vertices.\n let done = false;\n let t2 = tMax;\n let pushBackIter = 0;\n\n for (;;)\n {\n // Find the deepest point at t2. Store the witness point indices.\n const ret = b2FindMinSeparation(fcn, t2);\n let s2 = ret.separation;\n const indexA = ret.indexA;\n const indexB = ret.indexB;\n\n // Is the final configuration separated?\n if (s2 > target + tolerance)\n {\n // Victory!\n output.state = b2TOIState.b2_toiStateSeparated;\n output.t = tMax;\n done = true;\n\n break;\n }\n\n // Has the separation reached tolerance?\n if (s2 > target - tolerance)\n {\n // Advance the sweeps\n t1 = t2;\n\n break;\n }\n\n // Compute the initial separation of the witness points.\n let s1 = b2EvaluateSeparation(fcn, indexA, indexB, t1);\n\n // Check for initial overlap. This might happen if the root finder\n // runs out of iterations.\n if (s1 < target - tolerance)\n {\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Check for touching\n if (s1 <= target + tolerance)\n {\n // Victory! t1 should hold the TOI (could be 0.0).\n output.state = b2TOIState.b2_toiStateHit;\n output.t = t1;\n done = true;\n\n break;\n }\n\n // Compute 1D root of: f(x) - target = 0\n let rootIterCount = 0;\n let a1 = t1,\n a2 = t2;\n\n for (;;)\n {\n // Use a mix of the secant rule and bisection.\n let t;\n\n if (rootIterCount & 1)\n {\n // Secant rule to improve convergence.\n t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);\n }\n else\n {\n // Bisection to guarantee progress.\n t = 0.5 * (a1 + a2);\n }\n\n ++rootIterCount;\n\n const s = b2EvaluateSeparation(fcn, indexA, indexB, t);\n\n if (Math.abs(s - target) < tolerance)\n {\n // t2 holds a tentative value for t1\n t2 = t;\n\n break;\n }\n\n // Ensure we continue to bracket the root.\n if (s > target)\n {\n a1 = t;\n s1 = s;\n }\n else\n {\n a2 = t;\n s2 = s;\n }\n\n if (rootIterCount == 50)\n {\n break;\n }\n }\n\n ++pushBackIter;\n\n if (pushBackIter == B2_MAX_POLYGON_VERTICES)\n {\n break;\n }\n }\n\n ++iter;\n\n if (done)\n {\n break;\n }\n\n if (iter == k_maxIterations)\n {\n // Root finder got stuck. Semi-victory.\n output.state = b2TOIState.b2_toiStateFailed;\n output.t = t1;\n\n break;\n }\n }\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Hull } from './include/collision_h.js';\nimport { b2AABB, b2AABB_Center, b2Cross, b2DistanceSquared, b2Normalize, b2Sub } from './include/math_functions_h.js';\n\nimport { b2Validation } from './include/types_h.js';\nimport { b2_linearSlop } from './include/core_h.js';\n\n/**\n * @namespace Hull\n */\n\n// quickhull recursion\nfunction b2RecurseHull(p1, p2, ps, count)\n{\n const hull = new b2Hull();\n\n if (count === 0)\n {\n return hull;\n }\n\n // create an edge vector pointing from p1 to p2\n const e = b2Normalize(b2Sub(p2, p1));\n\n // discard points left of e and find point furthest to the right of e\n const rightPoints = [];\n let rightCount = 0;\n\n let bestIndex = 0;\n let bestDistance = b2Cross(b2Sub(ps[bestIndex], p1), e);\n\n if (bestDistance > 0.0)\n {\n rightPoints[rightCount++] = ps[bestIndex];\n }\n\n for (let i = 1; i < count; ++i)\n {\n const distance = b2Cross(b2Sub(ps[i], p1), e);\n\n if (distance > bestDistance)\n {\n bestIndex = i;\n bestDistance = distance;\n }\n\n if (distance > 0.0)\n {\n rightPoints[rightCount++] = ps[i];\n }\n }\n\n if (bestDistance < 2.0 * b2_linearSlop)\n {\n return hull;\n }\n\n const bestPoint = ps[bestIndex];\n\n // compute hull to the right of p1-bestPoint\n const hull1 = b2RecurseHull(p1, bestPoint, rightPoints, rightCount);\n\n // compute hull to the right of bestPoint-p2\n const hull2 = b2RecurseHull(bestPoint, p2, rightPoints, rightCount);\n\n // stitch together hulls\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = bestPoint;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n return hull;\n}\n\nexport function b2IsPolygonCCW(points, count)\n{\n let area = 0;\n\n for (let i = 0; i < count; i++)\n {\n const j = (i + 1) % count;\n area += (points[j].x - points[i].x) * (points[j].y + points[i].y);\n }\n\n return area < 0;\n}\n\nexport function b2ReverseWinding(points, count)\n{\n for (let i = 0; i < count / 2; i++)\n {\n const temp = points[i];\n points[i] = points[count - 1 - i];\n points[count - 1 - i] = temp;\n }\n\n return points;\n}\n\n// quickhull algorithm\n// - merges vertices based on b2_linearSlop\n// - removes collinear points using b2_linearSlop\n// - returns an empty hull if it fails\n\n/**\n * @function b2ComputeHull\n * @param {b2Vec2[]} points - Array of 2D points to compute hull from\n * @param {number} count - Number of points in the array\n * @returns {b2Hull} A hull object containing the computed convex hull vertices\n * @description\n * Computes the convex hull of a set of 2D points. The function:\n * - Filters duplicate points within a tolerance\n * - Finds extreme points to establish initial hull edges\n * - Recursively adds points to build the complete hull\n * - Removes collinear/near-collinear points from final hull\n * @throws {Error} If count < 3 or count > B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputeHull(points, count)\n{\n const hull = new b2Hull();\n\n if (count < 3 || count > B2_MAX_POLYGON_VERTICES)\n {\n // check your data\n console.assert(false, \"WARNING: not enough points in the hull.\");\n\n return hull;\n }\n\n // count = Math.min(count, B2_MAX_POLYGON_VERTICES);\n\n const aabb = new b2AABB(Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n // Perform aggressive point welding. First point always remains.\n // Also compute the bounding box for later.\n const ps = [];\n let n = 0;\n const tolSqr = 16.0 * b2_linearSlop * b2_linearSlop;\n\n for (let i = 0; i < count; ++i)\n {\n // aabb.lowerBound = b2Min(aabb.lowerBound, points[i]);\n aabb.lowerBoundX = Math.min(aabb.lowerBoundX, points[i].x);\n aabb.lowerBoundY = Math.min(aabb.lowerBoundY, points[i].y);\n\n // aabb.upperBound = b2Max(aabb.upperBound, points[i]);\n aabb.upperBoundX = Math.max(aabb.upperBoundX, points[i].x);\n aabb.upperBoundY = Math.max(aabb.upperBoundY, points[i].y);\n\n const vi = points[i];\n\n let unique = true;\n\n for (let j = 0; j < i; ++j)\n {\n const vj = points[j];\n\n const distSqr = b2DistanceSquared(vi, vj);\n\n if (distSqr < tolSqr)\n {\n unique = false;\n\n break;\n }\n }\n\n if (unique)\n {\n ps[n++] = vi;\n }\n }\n\n if (n < 3)\n {\n // too many points very close together, check your data and check your scale\n return hull;\n }\n\n // Find an extreme point as the first point on the hull\n const c = b2AABB_Center(aabb);\n let f1 = 0;\n let dsq1 = b2DistanceSquared(c, ps[f1]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(c, ps[i]);\n\n if (dsq > dsq1)\n {\n f1 = i;\n dsq1 = dsq;\n }\n }\n\n // remove p1 from working set\n const p1 = ps[f1];\n ps[f1] = ps[n - 1];\n n = n - 1;\n\n let f2 = 0;\n let dsq2 = b2DistanceSquared(p1, ps[f2]);\n\n for (let i = 1; i < n; ++i)\n {\n const dsq = b2DistanceSquared(p1, ps[i]);\n\n if (dsq > dsq2)\n {\n f2 = i;\n dsq2 = dsq;\n }\n }\n\n // remove p2 from working set\n const p2 = ps[f2];\n ps[f2] = ps[n - 1];\n n = n - 1;\n\n // split the points into points that are left and right of the line p1-p2.\n const rightPoints = [];\n let rightCount = 0;\n\n const leftPoints = [];\n let leftCount = 0;\n\n const e = b2Normalize(b2Sub(p2, p1));\n\n for (let i = 0; i < n; ++i)\n {\n const d = b2Cross(b2Sub(ps[i], p1), e);\n\n // slop used here to skip points that are very close to the line p1-p2\n if (d >= 2.0 * b2_linearSlop)\n {\n rightPoints[rightCount++] = ps[i];\n }\n else if (d <= -2.0 * b2_linearSlop)\n {\n leftPoints[leftCount++] = ps[i];\n }\n }\n\n // compute hulls on right and left\n const hull1 = b2RecurseHull(p1, p2, rightPoints, rightCount);\n const hull2 = b2RecurseHull(p2, p1, leftPoints, leftCount);\n\n if (hull1.count === 0 && hull2.count === 0)\n {\n // all points collinear\n return hull;\n }\n\n // stitch hulls together, preserving CCW winding order\n hull.points[hull.count++] = p1;\n\n for (let i = 0; i < hull1.count; ++i)\n {\n hull.points[hull.count++] = hull1.points[i];\n }\n\n hull.points[hull.count++] = p2;\n\n for (let i = 0; i < hull2.count; ++i)\n {\n hull.points[hull.count++] = hull2.points[i];\n }\n\n console.assert(hull.count <= B2_MAX_POLYGON_VERTICES);\n\n // merge collinear\n let searching = true;\n\n while (searching && hull.count > 2)\n {\n searching = false;\n\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const s1 = hull.points[i1];\n const s2 = hull.points[i2];\n const s3 = hull.points[i3];\n\n // unit edge vector for s1-s3\n const r = b2Normalize(b2Sub(s3, s1));\n\n const distance = b2Cross(b2Sub(s2, s1), r);\n\n if (distance <= 2.0 * b2_linearSlop)\n {\n // remove midpoint from hull\n for (let j = i2; j < hull.count - 1; ++j)\n {\n hull.points[j] = hull.points[j + 1];\n }\n hull.count -= 1;\n\n // continue searching for collinear points\n searching = true;\n\n break;\n }\n }\n }\n\n if (hull.count < 3)\n {\n // too many points collinear, shouldn't be reached since this was validated above\n hull.count = 0;\n }\n\n return hull;\n}\n\n/**\n * @function b2ValidateHull\n * @description\n * Validates that a hull meets the requirements for a valid convex polygon:\n * - Has between 3 and B2_MAX_POLYGON_VERTICES points\n * - Points are in counter-clockwise order\n * - All points are behind the edges\n * - No collinear points within b2_linearSlop tolerance\n * @param {b2Hull} hull - The hull to validate, containing points array and count\n * @returns {boolean} True if the hull is valid, false otherwise\n * @throws {Warning} Console warnings are issued explaining validation failures\n */\nexport function b2ValidateHull(hull)\n{\n if (!b2Validation)\n {\n return true;\n }\n\n if (hull.count < 3 || B2_MAX_POLYGON_VERTICES < hull.count)\n {\n console.warn(\"WARNING: hull does not have enough points.\");\n\n return false;\n }\n\n // hull must have CCW winding order for points\n if (!b2IsPolygonCCW(hull.points, hull.count))\n {\n console.warn(\"WARNING: hull does not have CCW winding.\");\n\n return false;\n }\n\n // test that every point is behind every edge\n for (let i = 0; i < hull.count; ++i)\n {\n // create an edge vector\n const i1 = i;\n const i2 = i < hull.count - 1 ? i1 + 1 : 0;\n const p = hull.points[i1];\n const e = b2Normalize(b2Sub(hull.points[i2], p));\n\n for (let j = 0; j < hull.count; ++j)\n {\n // skip points that subtend the current edge\n if (j === i1 || j === i2)\n {\n continue;\n }\n\n const distance = b2Cross(b2Sub(hull.points[j], p), e);\n\n if (distance >= 0.0)\n {\n console.warn(\"WARNING: hull points are not behind edges (?)\");\n\n return false;\n }\n }\n }\n\n // test for collinear points\n for (let i = 0; i < hull.count; ++i)\n {\n const i1 = i;\n const i2 = (i + 1) % hull.count;\n const i3 = (i + 2) % hull.count;\n\n const p1 = hull.points[i1];\n const p2 = hull.points[i2];\n const p3 = hull.points[i3];\n\n const e = b2Normalize(b2Sub(p3, p1));\n\n const distance = b2Cross(b2Sub(p2, p1), e);\n\n if (distance <= b2_linearSlop)\n {\n // p1-p2-p3 are collinear\n console.warn(\"WARNING: hull has collinear points.\");\n\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2CastOutput, b2Circle, b2DistanceCache, b2DistanceInput, b2MassData, b2Polygon, b2ShapeCastPairInput } from './include/collision_h.js';\nimport {\n b2AABB,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossVS,\n b2DistanceSquared,\n b2Dot,\n b2GetLengthAndNormalize,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2Max,\n b2Min,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2,\n b2Vec2_IsValid,\n eps\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2ShapeCast, b2ShapeDistance } from './include/distance_h.js';\n\nimport { B2_HUGE } from './include/core_h.js';\nimport { b2ValidateHull } from './include/hull_h.js';\n\n/**\n * @namespace Geometry\n */\n\n/**\n * Validates a ray cast input structure.\n * @function b2IsValidRay\n * @param {b2RayCastInput} input - The ray cast input to validate, containing:\n * - origin: b2Vec2 - Starting point of the ray\n * - translation: b2Vec2 - Direction and length of the ray\n * - maxFraction: number - Maximum fraction of translation to check\n * @returns {boolean} True if the ray cast input is valid, false otherwise.\n * @description\n * Checks if a ray cast input is valid by verifying:\n * - The origin vector is valid\n * - The translation vector is valid\n * - The maxFraction is a valid number\n * - The maxFraction is between 0 and B2_HUGE(exclusive)\n */\nexport function b2IsValidRay(input)\n{\n const isValid = b2Vec2_IsValid(input.origin) && b2Vec2_IsValid(input.translation) && b2IsValid(input.maxFraction) &&\n 0.0 <= input.maxFraction && input.maxFraction < B2_HUGE;\n\n return isValid;\n}\n\nfunction b2ComputePolygonCentroid(vertices, count)\n{\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const origin = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], origin);\n const e2 = b2Sub(vertices[i + 1], origin);\n const a = 0.5 * b2Cross(e1, e2);\n\n // Area weighted centroid\n center = b2MulAdd(center, a * inv3, b2Add(e1, e2));\n area += a;\n }\n\n // Centroid\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n\n // Restore offset\n center = b2Add(origin, center);\n\n return center;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakePolygon\n * @summary Creates a polygon shape from a hull with rounded corners.\n * @param {b2Hull} hull - A convex hull structure containing points that define the polygon vertices\n * @param {number} radius - The radius used to round the corners of the polygon\n * @param {boolean} [forceCheck=true] - Whether to enforce hull validation\n * @returns {b2Polygon} A new polygon shape with computed vertices, normals, and centroid\n * @throws {Error} Throws an assertion error if the hull is invalid\n * @description\n * Creates a b2Polygon from a convex hull. If the hull has fewer than 3 points, returns a\n * square shape. The function computes the polygon's vertices, edge normals, and centroid.\n * Each edge normal is a unit vector perpendicular to the corresponding edge.\n */\nexport function b2MakePolygon(hull, radius, forceCheck = true)\n{\n if (forceCheck && !b2ValidateHull(hull))\n {\n console.warn(\"Invalid hull.\");\n\n return null;\n }\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = hull.points[i];\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n// default to forceCheck: true - turn this off at your own peril, it validates the hull\n/**\n * @function b2MakeOffsetPolygon\n * @description Creates a polygon shape from a hull with specified radius and transform\n * @param {b2Hull} hull - The input hull to create the polygon from\n * @param {number} radius - The radius to offset the polygon vertices\n * @param {b2Transform} transform - Transform to apply to the hull points\n * @param {boolean} [forceCheck=true] - Whether to force validation check of the hull\n * @returns {b2Polygon} A new polygon shape with transformed vertices, computed normals and centroid\n * @throws {Error} Throws assertion error if hull validation fails\n * @note Returns a square polygon of size 0.5 if hull has less than 3 points\n */\nexport function b2MakeOffsetPolygon(hull, radius, transform, forceCheck = true)\n{\n console.assert(forceCheck && b2ValidateHull(hull), \"Invalid hull.\");\n\n if (hull.count < 3)\n {\n // Handle a bad hull when assertions are disabled\n return b2MakeSquare(0.5);\n }\n\n const shape = new b2Polygon();\n shape.count = hull.count;\n shape.radius = radius;\n\n // Copy vertices\n for (let i = 0; i < shape.count; ++i)\n {\n shape.vertices[i] = b2TransformPoint(transform, hull.points[i]);\n }\n\n // Compute normals. Ensure the edges have non-zero length.\n for (let i = 0; i < shape.count; ++i)\n {\n const i1 = i;\n const i2 = i + 1 < shape.count ? i + 1 : 0;\n const edge = b2Sub(shape.vertices[i2], shape.vertices[i1]);\n console.assert(b2Dot(edge, edge) > eps * eps);\n shape.normals[i] = b2Normalize(b2CrossVS(edge, 1.0));\n }\n\n shape.centroid = b2ComputePolygonCentroid(shape.vertices, shape.count);\n\n return shape;\n}\n\n/**\n * Creates a square polygon with equal width and height.\n * @function b2MakeSquare\n * @param {number} h - The half-width and half-height of the square.\n * @returns {b2Polygon} A polygon object representing a square centered at the origin.\n * @description\n * Creates a square polygon by calling b2MakeBox with equal dimensions.\n * The square is centered at the origin with sides of length 2h.\n */\nexport function b2MakeSquare(h)\n{\n return b2MakeBox(h, h);\n}\n\n/**\n * @function b2MakeBox\n * @description\n * Creates a rectangular polygon shape centered at the origin with specified half-widths.\n * The vertices are arranged counter-clockwise starting from the bottom-left corner.\n * The shape includes pre-computed normals for each edge.\n * @param {number} hx - Half-width of the box in the x-direction (must be positive)\n * @param {number} hy - Half-height of the box in the y-direction (must be positive)\n * @returns {b2Polygon} A polygon shape representing a rectangle with:\n * - 4 vertices at (-hx,-hy), (hx,-hy), (hx,hy), (-hx,hy)\n * - 4 normals pointing outward from each edge\n * - radius of 0\n * - centroid at (0,0)\n * @throws {Error} Throws an assertion error if hx or hy are not valid positive numbers\n */\nexport function b2MakeBox(hx, hy)\n{\n console.assert(b2IsValid(hx) && hx > 0.0);\n console.assert(b2IsValid(hy) && hy > 0.0);\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = new b2Vec2(-hx, -hy);\n shape.vertices[1] = new b2Vec2(hx, -hy);\n shape.vertices[2] = new b2Vec2(hx, hy);\n shape.vertices[3] = new b2Vec2(-hx, hy);\n shape.normals[0] = new b2Vec2(0.0, -1.0);\n shape.normals[1] = new b2Vec2(1.0, 0.0);\n shape.normals[2] = new b2Vec2(0.0, 1.0);\n shape.normals[3] = new b2Vec2(-1.0, 0.0);\n shape.radius = 0.0;\n shape.centroid = new b2Vec2(0,0);\n\n return shape;\n}\n\n/**\n * Creates a rounded box shape by generating a box with specified dimensions and corner radius.\n * @function b2MakeRoundedBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {number} radius - Radius of the rounded corners\n * @returns {b2Polygon} A polygon shape representing a rounded box\n */\nexport function b2MakeRoundedBox(hx, hy, radius)\n{\n const shape = b2MakeBox(hx, hy);\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * Creates a rectangular polygon shape with specified dimensions, position, and rotation.\n * @function b2MakeOffsetBox\n * @param {number} hx - Half-width of the box along the x-axis\n * @param {number} hy - Half-height of the box along the y-axis\n * @param {b2Vec2} center - The center position of the box\n * @param {b2Rot} rotation - The 2D rotation of the box\n * @returns {b2Polygon} A polygon shape representing the box with 4 vertices and normals\n * @description\n * Creates a b2Polygon representing a rectangle with the given dimensions. The box is centered\n * at the specified position and rotated by the given angle. The resulting polygon includes\n * 4 vertices, 4 normals, and has its centroid set to the center position.\n */\nexport function b2MakeOffsetBox(hx, hy, center, rotation)\n{\n const xf = new b2Transform();\n xf.p = center;\n xf.q = rotation;\n\n const shape = new b2Polygon();\n shape.count = 4;\n shape.vertices[0] = b2TransformPoint(xf, new b2Vec2(-hx, -hy));\n shape.vertices[1] = b2TransformPoint(xf, new b2Vec2(hx, -hy));\n shape.vertices[2] = b2TransformPoint(xf, new b2Vec2(hx, hy));\n shape.vertices[3] = b2TransformPoint(xf, new b2Vec2(-hx, hy));\n shape.normals[0] = b2RotateVector(xf.q, new b2Vec2(0.0, -1.0));\n shape.normals[1] = b2RotateVector(xf.q, new b2Vec2(1.0, 0.0));\n shape.normals[2] = b2RotateVector(xf.q, new b2Vec2(0.0, 1.0));\n shape.normals[3] = b2RotateVector(xf.q, new b2Vec2(-1.0, 0.0));\n shape.radius = 0.0;\n shape.centroid = center;\n\n return shape;\n}\n\n/**\n * @function b2TransformPolygon\n * @summary Transforms a polygon by applying a rigid body transformation.\n * @param {b2Transform} transform - The transformation to apply, consisting of a position vector and rotation.\n * @param {b2Polygon} polygon - The polygon to transform, containing vertices, normals and centroid.\n * @returns {b2Polygon} The transformed polygon with updated vertices, normals and centroid.\n * @description\n * Applies a rigid body transformation to a polygon by:\n * 1. Transforming each vertex using the full transform\n * 2. Rotating each normal vector using only the rotation component\n * 3. Transforming the centroid using the full transform\n */\nexport function b2TransformPolygon(transform, polygon)\n{\n const p = polygon;\n\n for (let i = 0; i < p.count; ++i)\n {\n p.vertices[i] = b2TransformPoint(transform, p.vertices[i]);\n p.normals[i] = b2RotateVector(transform.q, p.normals[i]);\n }\n\n p.centroid = b2TransformPoint(transform, p.centroid);\n\n return p;\n}\n\n/**\n * @function b2ComputeCircleMass\n * @summary Computes mass properties for a circle shape.\n * @param {b2Circle} shape - A circle shape object containing radius and center properties\n * @param {number} density - The density of the circle in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the circle\n * - center: The center of mass (copied from shape.center)\n * - rotationalInertia: The rotational inertia about the center of mass\n * @description\n * Calculates the mass, center of mass, and rotational inertia for a circle shape\n * with given density. The rotational inertia is computed about the center of mass\n * using the parallel axis theorem when the circle's center is offset from the origin.\n */\nexport function b2ComputeCircleMass(shape, density)\n{\n const rr = shape.radius * shape.radius;\n\n const massData = new b2MassData();\n massData.mass = density * Math.PI * rr;\n massData.center = shape.center.clone();\n\n // inertia about the local origin\n massData.rotationalInertia = massData.mass * (0.5 * rr + b2Dot(shape.center, shape.center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCapsuleMass\n * @description\n * Computes mass properties for a capsule shape, including total mass, center of mass,\n * and rotational inertia. A capsule consists of a rectangle with semicircles at both ends.\n * @param {b2Capsule} shape - A capsule shape defined by two centers (center1, center2) and a radius\n * @param {number} density - The density of the capsule in mass per unit area\n * @returns {b2MassData} An object containing:\n * - mass: The total mass of the capsule\n * - center: A b2Vec2 representing the center of mass\n * - rotationalInertia: The moment of inertia about the center of mass\n */\nexport function b2ComputeCapsuleMass(shape, density)\n{\n const radius = shape.radius;\n const rr = radius * radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n const length = b2Length(b2Sub(p2, p1));\n const ll = length * length;\n\n const circleMass = density * Math.PI * rr;\n const boxMass = density * (2.0 * radius * length);\n\n const massData = new b2MassData();\n massData.mass = circleMass + boxMass;\n massData.center = new b2Vec2(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y));\n\n // two offset half circles, both halves add up to full circle and each half is offset by half length\n // semi-circle centroid = 4 r / 3 pi\n // Need to apply parallel-axis theorem twice:\n // 1. shift semi-circle centroid to origin\n // 2. shift semi-circle to box end\n // m * ((h + lc)^2 - lc^2) = m * (h^2 + 2 * h * lc)\n // See = https://en.wikipedia.org/wiki/Parallel_axis_theorem\n // I verified this formula by computing the convex hull of a 128 vertex capsule\n\n // half circle centroid\n const lc = 4.0 * radius / (3.0 * Math.PI);\n\n // half length of rectangular portion of capsule\n const h = 0.5 * length;\n\n const circleInertia = circleMass * (0.5 * rr + h * h + 2.0 * h * lc);\n const boxInertia = boxMass * (4.0 * rr + ll) / 12.0;\n massData.rotationalInertia = circleInertia + boxInertia;\n\n // inertia about the local origin\n massData.rotationalInertia += massData.mass * b2Dot(massData.center, massData.center);\n\n return massData;\n}\n\n/**\n * @function b2ComputePolygonMass\n * @description\n * Computes mass properties for a polygon shape, including mass, center of mass, and rotational inertia.\n * Handles special cases for 1-vertex (circle) and 2-vertex (capsule) polygons.\n * For polygons with 3 or more vertices, calculates properties using triangulation.\n * @param {b2Polygon} shape - The polygon shape containing vertices, normals, count, and radius\n * @param {number} density - The density of the shape in mass per unit area\n * @returns {b2MassData} Object containing:\n * - mass: Total mass of the shape\n * - center: Center of mass as b2Vec2\n * - rotationalInertia: Moment of inertia about the center of mass\n * @throws {Error} Throws assertion error if shape.count is 0 or exceeds B2_MAX_POLYGON_VERTICES\n */\nexport function b2ComputePolygonMass(shape, density)\n{\n console.assert(shape.count > 0);\n\n if (shape.count == 1)\n {\n const circle = new b2Circle();\n circle.center = shape.vertices[0].clone();\n circle.radius = shape.radius;\n\n return b2ComputeCircleMass(circle, density);\n }\n\n if (shape.count == 2)\n {\n const capsule = new b2Capsule();\n capsule.center1 = shape.vertices[0].clone();\n capsule.center2 = shape.vertices[1].clone();\n capsule.radius = shape.radius;\n\n return b2ComputeCapsuleMass(capsule, density);\n }\n\n const vertices = new Array(B2_MAX_POLYGON_VERTICES);\n const count = shape.count;\n const radius = shape.radius;\n console.assert(count <= B2_MAX_POLYGON_VERTICES); // PJB: ragdolls crash at 8, maxPolygonVertices == 8, coincidence?\n\n if (radius > 0.0)\n {\n // Approximate mass of rounded polygons by pushing out the vertices.\n const sqrt2 = 1.412;\n\n for (let i = 0; i < count; ++i)\n {\n const j = i == 0 ? count - 1 : i - 1;\n const n1 = shape.normals[j];\n const n2 = shape.normals[i];\n\n const mid = b2Normalize(b2Add(n1, n2));\n vertices[i] = b2MulAdd(shape.vertices[i], sqrt2 * radius, mid);\n }\n }\n else\n {\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = shape.vertices[i];\n }\n }\n\n let center = new b2Vec2(0.0, 0.0);\n let area = 0.0;\n let rotationalInertia = 0.0;\n\n // Get a reference point for forming triangles.\n // Use the first vertex to reduce round-off errors.\n const r = vertices[0];\n\n const inv3 = 1.0 / 3.0;\n\n for (let i = 1; i < count - 1; ++i)\n {\n // Triangle edges\n const e1 = b2Sub(vertices[i], r);\n const e2 = b2Sub(vertices[i + 1], r);\n\n const D = b2Cross(e1, e2);\n\n const triangleArea = 0.5 * D;\n area += triangleArea;\n\n // Area weighted centroid, r at origin\n center = b2MulAdd(center, triangleArea * inv3, b2Add(e1, e2));\n\n const ex1 = e1.x,\n ey1 = e1.y;\n const ex2 = e2.x,\n ey2 = e2.y;\n\n const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;\n const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;\n\n rotationalInertia += (0.25 * inv3 * D) * (intx2 + inty2);\n }\n\n const massData = new b2MassData();\n\n // Total mass\n massData.mass = density * area;\n\n // Center of mass, shift back from origin at r\n console.assert(area > eps);\n const invArea = 1.0 / area;\n center.x *= invArea;\n center.y *= invArea;\n massData.center = b2Add(r, center);\n\n // Inertia tensor relative to the local origin (point s).\n massData.rotationalInertia = density * rotationalInertia;\n\n // Shift to center of mass then to original body origin.\n massData.rotationalInertia += massData.mass * (b2Dot(massData.center, massData.center) - b2Dot(center, center));\n\n return massData;\n}\n\n/**\n * @function b2ComputeCircleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a circle shape after applying a transform.\n * @param {b2Circle} shape - The circle shape containing center point and radius.\n * @param {b2Transform} xf2 - The transform to be applied, consisting of a position (p) and rotation (q).\n * @returns {b2AABB} An AABB object defined by minimum and maximum points that bound the transformed circle.\n * @description\n * Calculates the AABB by transforming the circle's center point using the provided transform\n * and extending the bounds by the circle's radius in each direction.\n */\nexport function b2ComputeCircleAABB(shape, xf)\n{\n // let p = b2TransformPoint(xf, shape.center);\n const pX = (xf.q.c * shape.center.x - xf.q.s * shape.center.y) + xf.p.x;\n const pY = (xf.q.s * shape.center.x + xf.q.c * shape.center.y) + xf.p.y;\n const r = shape.radius;\n\n const aabb = new b2AABB(pX - r, pY - r, pX + r, pY + r);\n\n return aabb;\n}\n\n/**\n * @function b2ComputeCapsuleAABB\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a capsule shape.\n * @param {b2Capsule} shape - A capsule shape defined by two centers and a radius.\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the capsule.\n * @returns {b2AABB} An AABB that encompasses the transformed capsule shape.\n * @description\n * Calculates the minimum and maximum bounds of a capsule after applying a transform.\n * The AABB is computed by transforming the capsule's center points and extending\n * the bounds by the capsule's radius in all directions.\n */\nexport function b2ComputeCapsuleAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.center1);\n const v2 = b2TransformPoint(xf, shape.center2);\n\n const lowerX = Math.min(v1.x, v2.x) - shape.radius;\n const lowerY = Math.min(v1.y, v2.y) - shape.radius;\n const upperX = Math.max(v1.x, v2.x) + shape.radius;\n const upperY = Math.max(v1.y, v2.y) + shape.radius;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @function b2ComputePolygonAABB\n * @description\n * Computes the Axis-Aligned Bounding Box (AABB) for a polygon shape after applying a transform.\n * The AABB includes the polygon's radius in its calculations.\n * @param {b2Polygon} shape - The polygon shape containing vertices and radius\n * @param {b2Transform} xf2 - The transform to apply, consisting of position (p) and rotation (q)\n * @returns {b2AABB} An AABB object with lower and upper bounds that encompass the transformed polygon\n */\nexport function b2ComputePolygonAABB(shape, xf)\n{\n // let lower = b2TransformPoint(xf, shape.vertices[0]);\n const sv = shape.vertices[0];\n let lowerX = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n let lowerY = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n let upperX = lowerX,\n upperY = lowerY;\n\n for (let i = 1; i < shape.count; ++i)\n {\n // let v = b2TransformPoint(xf, shape.vertices[i]);\n const sv = shape.vertices[i];\n const vx = (xf.q.c * sv.x - xf.q.s * sv.y) + xf.p.x;\n const vy = (xf.q.s * sv.x + xf.q.c * sv.y) + xf.p.y;\n\n // lower = b2Min(lower, v);\n lowerX = Math.min(lowerX, vx);\n lowerY = Math.min(lowerY, vy);\n\n // upper = b2Max(upper, v);\n upperX = Math.max(upperX, vx);\n upperY = Math.max(upperY, vy);\n }\n\n const r = shape.radius;\n\n // lower = b2Sub(lower, r);\n lowerX -= r;\n lowerY -= r;\n\n // upper = b2Add(upper, r);\n upperX += r;\n upperY += r;\n\n const aabb = new b2AABB(lowerX, lowerY, upperX, upperY);\n\n return aabb;\n}\n\n/**\n * @summary Computes an Axis-Aligned Bounding Box (AABB) for a line segment.\n * @function b2ComputeSegmentAABB\n * @param {b2Segment} shape - A line segment defined by two points (point1 and point2)\n * @param {b2Transform} xf2 - A transform containing position and rotation to be applied to the segment\n * @returns {b2AABB} An AABB that contains the transformed line segment\n * @description\n * Transforms the segment's endpoints using the provided transform, then creates an AABB\n * that encompasses the transformed segment by finding the minimum and maximum coordinates\n * of the transformed endpoints.\n */\nexport function b2ComputeSegmentAABB(shape, xf)\n{\n const v1 = b2TransformPoint(xf, shape.point1);\n const v2 = b2TransformPoint(xf, shape.point2);\n\n const lower = b2Min(v1, v2);\n const upper = b2Max(v1, v2);\n\n const aabb = new b2AABB(lower.x, lower.y, upper.x, upper.y);\n\n return aabb;\n}\n\n/**\n * @summary Determines if a point lies within a circle.\n * @function b2PointInCircle\n * @param {b2Vec2} point - The point to test, represented as a 2D vector.\n * @param {b2Circle} shape - The circle to test against, containing center and radius properties.\n * @returns {boolean} True if the point lies within or on the circle's boundary, false otherwise.\n * @description\n * Tests if a point lies within a circle by comparing the squared distance between\n * the point and circle's center against the circle's squared radius.\n */\nexport function b2PointInCircle(point, shape)\n{\n const center = shape.center;\n\n return b2DistanceSquared(point, center) <= shape.radius * shape.radius;\n}\n\n/**\n * @function b2PointInCapsule\n * @summary Tests if a point lies inside a capsule shape.\n * @param {b2Vec2} point - The point to test\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {boolean} True if the point lies inside or on the capsule, false otherwise\n * @description\n * A capsule is defined by two end centers (center1 and center2) and a radius.\n * The function calculates if the given point lies within the capsule by:\n * 1. Testing if the capsule has zero length (centers are identical)\n * 2. If not, finding the closest point on the line segment between centers\n * 3. Checking if the distance from the test point to the closest point is within the radius\n */\nexport function b2PointInCapsule(point, shape)\n{\n const rr = shape.radius * shape.radius;\n const p1 = shape.center1;\n const p2 = shape.center2;\n\n const d = b2Sub(p2, p1);\n const dd = b2Dot(d, d);\n\n if (dd == 0.0)\n {\n // Capsule is really a circle\n return b2DistanceSquared(point, p1) <= rr;\n }\n\n // Get closest point on capsule segment\n // c = p1 + t * d\n // dot(point - c, d) = 0\n // dot(point - p1 - t * d, d) = 0\n // t = dot(point - p1, d) / dot(d, d)\n let t = b2Dot(b2Sub(point, p1), d) / dd;\n t = b2ClampFloat(t, 0.0, 1.0);\n const c = b2MulAdd(p1, t, d);\n\n // Is query point within radius around closest point?\n return b2DistanceSquared(point, c) <= rr;\n}\n\n/**\n * @function b2PointInPolygon\n * @description\n * Tests if a point lies inside a polygon shape by calculating the minimum distance\n * between the point and the polygon.\n * @param {b2Vec2} point - The point to test\n * @param {b2Polygon} shape - The polygon shape to test against\n * @returns {boolean} True if the point is inside or on the polygon (within shape.radius), false otherwise\n */\nexport function b2PointInPolygon(point, shape)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy(shape.vertices, shape.count, 0.0);\n input.proxyB = b2MakeProxy([ point ], 1, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance <= shape.radius;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\n/**\n * @function b2RayCastCircle\n * @summary Performs a ray cast against a circle shape.\n * @param {b2RayCastInput} input - The ray cast input parameters containing:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Circle} shape - The circle shape to test against, containing:\n * - center: b2Vec2 position of circle center\n * - radius: number radius of the circle\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean whether the ray intersects the circle\n * - point: b2Vec2 point of intersection if hit is true\n * - normal: b2Vec2 surface normal at intersection point if hit is true\n * - fraction: number intersection distance as a fraction of ray length if hit is true\n * @description\n * Calculates the intersection point between a ray and a circle shape.\n * Returns early with no hit if the ray length is 0 or if the ray passes outside the circle radius.\n */\nexport function b2RayCastCircle(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const p = shape.center.clone();\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n // Shift ray so circle center is the origin\n const s = b2Sub(input.origin, p);\n const res = b2GetLengthAndNormalize(input.translation);\n const length = res.length;\n\n if (length == 0.0)\n {\n // zero length ray\n return output;\n }\n const d = res.normal;\n\n // Find closest point on ray to origin\n\n // solve = dot(s + t * d, d) = 0\n const t = -b2Dot(s, d);\n\n // c is the closest point on the line to the origin\n const c = b2MulAdd(s, t, d);\n\n const cc = b2Dot(c, c);\n const r = shape.radius;\n const rr = r * r;\n\n if (cc > rr)\n {\n // closest point is outside the circle\n return output;\n }\n\n // Pythagoras\n const h = Math.sqrt(rr - cc);\n\n const fraction = t - h;\n\n if (fraction < 0.0 || input.maxFraction * length < fraction)\n {\n // outside the range of the ray segment\n return output;\n }\n\n const hitPoint = b2MulAdd(s, fraction, d);\n\n output.fraction = fraction / length;\n output.normal = b2Normalize(hitPoint);\n output.point = b2MulAdd(p, shape.radius, output.normal);\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastCapsule\n * @description\n * Performs a ray cast against a capsule shape. A capsule is defined by two centers and a radius.\n * If the capsule length is near zero, it degrades to a circle ray cast.\n * @param {b2RayCastInput} input - Contains ray cast parameters including:\n * - origin: b2Vec2 starting point of the ray\n * - translation: b2Vec2 direction and length of the ray\n * - maxFraction: number maximum intersection distance as a fraction of ray length\n * @param {b2Capsule} shape - The capsule to test against, containing:\n * - center1: b2Vec2 first endpoint of capsule centerline\n * - center2: b2Vec2 second endpoint of capsule centerline\n * - radius: number radius of the capsule\n * @returns {b2CastOutput} Contains the ray cast results:\n * - fraction: number intersection distance as a fraction of ray length\n * - point: b2Vec2 point of intersection\n * - normal: b2Vec2 surface normal at intersection\n * - hit: boolean whether an intersection occurred\n */\nexport function b2RayCastCapsule(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const v1 = shape.center1;\n const v2 = shape.center2;\n\n const e = b2Sub(v2, v1);\n\n const res = b2GetLengthAndNormalize(e);\n const capsuleLength = res.length;\n const a = res.normal;\n\n if (capsuleLength < eps)\n {\n // Capsule is really a circle\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n const p1 = input.origin;\n const d = input.translation;\n\n // Ray from capsule start to ray start\n const q = b2Sub(p1, v1);\n const qa = b2Dot(q, a);\n\n // Vector to ray start that is perpendicular to capsule axis\n const qp = b2MulAdd(q, -qa, a);\n\n const radius = shape.radius;\n\n // Does the ray start within the infinite length capsule?\n if (b2Dot(qp, qp) < radius * radius)\n {\n if (qa < 0.0)\n {\n // start point behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n if (qa > 1.0)\n {\n // start point ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n\n // ray starts inside capsule -> no hit\n return output;\n }\n\n // Perpendicular to capsule axis, pointing right\n let n = new b2Vec2(a.y, -a.x);\n\n const res0 = b2GetLengthAndNormalize(d);\n const rayLength = res0.length;\n const u = res0.normal;\n\n // Intersect ray with infinite length capsule\n // v1 + radius * n + s1 * a = p1 + s2 * u\n // v1 - radius * n + s1 * a = p1 + s2 * u\n\n // s1 * a - s2 * u = b\n // b = q - radius * ap\n // or\n // b = q + radius * ap\n\n // Cramer's rule [a -u]\n const den = -a.x * u.y + u.x * a.y;\n\n if (-eps < den && den < eps)\n {\n // Ray is parallel to capsule and outside infinite length capsule\n return output;\n }\n\n const b1 = b2MulSub(q, radius, n);\n const b2 = b2MulAdd(q, radius, n);\n\n const invDen = 1.0 / den;\n\n // Cramer's rule [a b1]\n const s21 = (a.x * b1.y - b1.x * a.y) * invDen;\n\n // Cramer's rule [a b2]\n const s22 = (a.x * b2.y - b2.x * a.y) * invDen;\n\n let s2, b;\n\n if (s21 < s22)\n {\n s2 = s21;\n b = b1;\n }\n else\n {\n s2 = s22;\n b = b2;\n n = b2Neg(n);\n }\n\n if (s2 < 0.0 || input.maxFraction * rayLength < s2)\n {\n return output;\n }\n\n // Cramer's rule [b -u]\n const s1 = (-b.x * u.y + u.x * b.y) * invDen;\n\n if (s1 < 0.0)\n {\n // ray passes behind capsule segment\n const circle = new b2Circle();\n circle.center = v1;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else if (capsuleLength < s1)\n {\n // ray passes ahead of capsule segment\n const circle = new b2Circle();\n circle.center = v2;\n circle.radius = shape.radius;\n\n return b2RayCastCircle(input, circle);\n }\n else\n {\n // ray hits capsule side\n output.fraction = s2 / rayLength;\n output.point = b2Add(b2Lerp(v1, v2, s1 / capsuleLength), b2MulSV(shape.radius, n));\n output.normal = n;\n output.hit = true;\n\n return output;\n }\n}\n\n/**\n * @function b2RayCastSegment\n * @description\n * Performs a ray cast against a line segment, determining if and where the ray intersects the segment.\n * For one-sided segments, intersections are only detected from one side based on a cross product test.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction for the ray\n * @param {b2Segment} shape - The line segment defined by two points (point1 and point2)\n * @param {boolean} oneSided - Whether to treat the segment as one-sided\n * @returns {b2CastOutput} Contains hit status, intersection point, normal, and fraction along the ray\n */\nexport function b2RayCastSegment(input, shape, oneSided)\n{\n if (oneSided)\n {\n // Skip left-side collision\n const offset = b2Cross(b2Sub(input.origin, shape.point1), b2Sub(shape.point2, shape.point1));\n\n if (offset < 0.0)\n {\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n return output;\n }\n }\n\n // Put the ray into the edge's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n const v1 = shape.point1;\n const v2 = shape.point2;\n const e = b2Sub(v2, v1);\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n const res = b2GetLengthAndNormalize(e);\n const length = res.length;\n const eUnit = res.normal;\n\n if (length == 0.0)\n {\n return output;\n }\n\n // Normal points to the right, looking from v1 towards v2\n let normal = b2RightPerp(eUnit);\n\n // Intersect ray with infinite segment using normal\n // Similar to intersecting a ray with an infinite plane\n // p = p1 + t * d\n // dot(normal, p - v1) = 0\n // dot(normal, p1 - v1) + t * dot(normal, d) = 0\n const numerator = b2Dot(normal, b2Sub(v1, p1));\n const denominator = b2Dot(normal, d);\n\n if (denominator == 0.0)\n {\n // parallel\n return output;\n }\n\n const t = numerator / denominator;\n\n if (t < 0.0 || input.maxFraction < t)\n {\n // out of ray range\n return output;\n }\n\n // Intersection point on infinite segment\n const p = b2MulAdd(p1, t, d);\n\n // Compute position of p along segment\n // p = v1 + s * e\n // s = dot(p - v1, e) / dot(e, e)\n\n const s = b2Dot(b2Sub(p, v1), eUnit);\n\n if (s < 0.0 || length < s)\n {\n // out of segment range\n return output;\n }\n\n if (numerator > 0.0)\n {\n normal = b2Neg(normal);\n }\n\n output.fraction = t;\n output.point = b2MulAdd(p1, t, d);\n output.normal = normal;\n output.hit = true;\n\n return output;\n}\n\n/**\n * @function b2RayCastPolygon\n * @description\n * Performs a ray cast against a polygon shape, detecting intersection points and normals.\n * For non-zero radius polygons, converts the ray cast into a shape cast operation.\n * @param {b2RayCastInput} input - Contains origin point, translation vector, and max fraction\n * @param {b2Polygon} shape - The polygon to test against, containing vertices, normals, count and radius\n * @returns {b2CastOutput} Contains:\n * - hit: boolean indicating if intersection occurred\n * - point: intersection point (if hit is true)\n * - normal: surface normal at intersection (if hit is true)\n * - fraction: fraction of translation where intersection occurred (if hit is true)\n * @throws {Error} Throws assertion error if input ray is invalid\n */\nexport function b2RayCastPolygon(input, shape)\n{\n console.assert(b2IsValidRay(input));\n\n if (shape.radius === 0.0)\n {\n // Put the ray into the polygon's frame of reference.\n const p1 = input.origin;\n const d = input.translation;\n\n let lower = 0.0,\n upper = input.maxFraction;\n\n let index = -1;\n\n const output = new b2CastOutput(rayNormal, rayPoint);\n\n for (let i = 0; i < shape.count; ++i)\n {\n // p = p1 + a * d\n // dot(normal, p - v) = 0\n // dot(normal, p1 - v) + a * dot(normal, d) = 0\n const numerator = b2Dot(shape.normals[i], b2Sub(shape.vertices[i], p1));\n const denominator = b2Dot(shape.normals[i], d);\n\n if (denominator === 0.0)\n {\n if (numerator < 0.0)\n {\n return output;\n }\n }\n else\n {\n // Note = we want this predicate without division:\n // lower < numerator / denominator, where denominator < 0\n // Since denominator < 0, we have to flip the inequality:\n // lower < numerator / denominator <==> denominator * lower > numerator.\n if (denominator < 0.0 && numerator < lower * denominator)\n {\n // Increase lower.\n // The segment enters this half-space.\n lower = numerator / denominator;\n index = i;\n }\n else if (denominator > 0.0 && numerator < upper * denominator)\n {\n // Decrease upper.\n // The segment exits this half-space.\n upper = numerator / denominator;\n }\n }\n\n if (upper < lower)\n {\n return output;\n }\n }\n\n console.assert(0.0 <= lower && lower <= input.maxFraction);\n\n if (index >= 0)\n {\n output.fraction = lower;\n output.normal = shape.normals[index];\n output.point = b2MulAdd(p1, lower, d);\n output.hit = true;\n }\n\n return output;\n }\n\n // TODO_ERIN this is not working for ray vs box (zero radii)\n const castInput = new b2ShapeCastPairInput();\n castInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n castInput.proxyB = b2MakeProxy([ input.origin ], 1, 0.0);\n castInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n castInput.translationB = input.translation;\n castInput.maxFraction = input.maxFraction;\n\n return b2ShapeCast(castInput);\n}\n\n/**\n * @function b2ShapeCastCircle\n * @description\n * Performs shape casting between a circle and a set of points with radius.\n * @param {b2ShapeCastInput} input - Contains points array, count, radius, translation and maxFraction\n * @param {b2Circle} shape - Circle shape with center point and radius\n * @returns {b2CastOutput} The shape cast result containing intersection details\n */\nexport function b2ShapeCastCircle(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center.clone() ], 1, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastCapsule\n * @description\n * Performs shape casting for a capsule shape against a set of points.\n * @param {b2ShapeCastInput} input - Contains the target points, count, radius,\n * translation, and maxFraction for the shape cast\n * @param {b2Capsule} shape - The capsule shape defined by two centers and a radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastCapsule(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.center1, shape.center2 ], 2, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastSegment\n * @param {b2ShapeCastInput} input - Contains shape points, count, radius, translation, and maxFraction\n * @param {b2Segment} shape - A segment defined by two points (point1 and point2)\n * @returns {b2CastOutput} The result of the shape cast operation\n * @description\n * Performs a shape cast operation between a segment and another shape. The function creates\n * proxies for both shapes, sets up their initial transforms, and performs the cast operation\n * using the specified translation and maximum fraction.\n */\nexport function b2ShapeCastSegment(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy([ shape.point1, shape.point2 ], 2, 0.0);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n\n/**\n * @function b2ShapeCastPolygon\n * @description\n * Performs shape casting between a polygon shape and a set of points, checking for collisions\n * along a translation path.\n * @param {b2ShapeCastInput} input - Contains the points, count, radius, translation, and maxFraction for the cast\n * @param {b2Polygon} shape - The polygon shape to test against, containing vertices, count, and radius\n * @returns {b2CastOutput} The result of the shape cast operation\n */\nexport function b2ShapeCastPolygon(input, shape)\n{\n const pairInput = new b2ShapeCastPairInput();\n pairInput.proxyA = b2MakeProxy(shape.vertices, shape.count, shape.radius);\n pairInput.proxyB = b2MakeProxy(input.points, input.count, input.radius);\n pairInput.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n pairInput.translationB = input.translation;\n pairInput.maxFraction = input.maxFraction;\n\n const output = b2ShapeCast(pairInput);\n\n return output;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_aabbMargin, b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase_CreateProxy, b2BroadPhase_DestroyProxy, b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport {\n b2AABB,\n b2DistanceSquared,\n b2Dot,\n b2InvRotateVector,\n b2InvTransformPoint,\n b2IsValid,\n b2Length,\n b2LengthSquared,\n b2Lerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyType, b2DefaultShapeDef, b2ShapeType } from './include/types_h.js';\nimport { b2CastOutput, b2ChainSegment, b2Circle, b2DistanceCache, b2DistanceInput, b2DistanceProxy, b2MassData, b2RayCastInput, b2Segment } from './include/collision_h.js';\nimport { b2ChainId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ChainShape, b2Shape, b2ShapeExtent } from './include/shape_h.js';\nimport {\n b2ComputeCapsuleAABB,\n b2ComputeCapsuleMass,\n b2ComputeCircleAABB,\n b2ComputeCircleMass,\n b2ComputePolygonAABB,\n b2ComputePolygonMass,\n b2ComputeSegmentAABB,\n b2PointInCapsule,\n b2PointInCircle,\n b2PointInPolygon,\n b2RayCastCapsule,\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastSegment,\n b2ShapeCastCapsule,\n b2ShapeCastCircle,\n b2ShapeCastPolygon,\n b2ShapeCastSegment,\n} from './include/geometry_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransform, b2GetBodyTransformQuick, b2MakeBodyId, b2UpdateBodyMassData } from './include/body_h.js';\nimport { b2GetWorld, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from './include/world_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\n\n/**\n * @namespace Shape\n */\n\nfunction b2GetShape(world, shapeId)\n{\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n const shape = world.shapeArray[id];\n\n return shape;\n}\n\n\nfunction b2GetChainShape(world, chainId)\n{\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n const chain = world.chainArray[id];\n\n return chain;\n}\n\nfunction b2UpdateShapeAABBs(shape, transform, proxyType)\n{\n const speculativeDistance = b2_speculativeDistance;\n const aabbMargin = b2_aabbMargin;\n\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n const margin = proxyType == b2BodyType.b2_staticBody ? speculativeDistance : aabbMargin;\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n}\n\nfunction b2CreateShapeInternal(world, body, transform, def, geometry, shapeType)\n{\n // B2_ASSERT(b2IsValid(def.density) && def.density >= 0.0);\n // B2_ASSERT(b2IsValid(def.friction) && def.friction >= 0.0);\n // B2_ASSERT(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const shapeId = b2AllocId(world.shapeIdPool);\n\n if (shapeId == world.shapeArray.length)\n {\n world.shapeArray.push(new b2Shape());\n }\n \n // eLse: B2_ASSERT(world.shapeArray[shapeId].id == B2_NULL_INDEX);\n\n // b2CheckIndex(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n switch (shapeType)\n {\n case b2ShapeType.b2_capsuleShape:\n shape.capsule = geometry;\n\n break;\n\n case b2ShapeType.b2_circleShape:\n shape.circle = geometry;\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n shape.polygon = geometry;\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n shape.segment = geometry;\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n shape.chainSegment = geometry;\n\n break;\n\n default:\n // B2_ASSERT(false);\n break;\n }\n\n shape.id = shapeId;\n shape.bodyId = body.id;\n shape.type = shapeType;\n shape.density = def.density;\n shape.friction = def.friction;\n shape.restitution = def.restitution;\n shape.filter = def.filter;\n shape.userData = def.userData;\n shape.customColor = def.customColor;\n shape.isSensor = def.isSensor;\n shape.enlargedAABB = false;\n shape.enableSensorEvents = def.enableSensorEvents;\n shape.enableContactEvents = def.enableContactEvents;\n shape.enableHitEvents = def.enableHitEvents;\n shape.enablePreSolveEvents = def.enablePreSolveEvents;\n shape.isFast = false;\n shape.proxyKey = B2_NULL_INDEX;\n shape.localCentroid = b2GetShapeCentroid(shape);\n shape.aabb = new b2AABB();\n shape.fatAABB = new b2AABB();\n shape.revision += 1;\n\n if (body.setIndex != b2SetType.b2_disabledSet)\n {\n const proxyType = body.type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, def.forceContactCreation || def.isSensor);\n }\n\n if (body.headShapeId != B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, body.headShapeId);\n const headShape = world.shapeArray[body.headShapeId];\n headShape.prevShapeId = shapeId;\n }\n\n shape.prevShapeId = B2_NULL_INDEX;\n shape.nextShapeId = body.headShapeId;\n body.headShapeId = shapeId;\n body.shapeCount += 1;\n\n b2ValidateSolverSets(world);\n\n return shape;\n}\n\nexport function b2CreateShape(bodyId, def, geometry, shapeType)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.density) && def.density >= 0.0);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ShapeId( 0, 0, 0 );\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const shape = b2CreateShapeInternal(world, body, transform, def, geometry, shapeType);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n\n b2ValidateSolverSets(world);\n\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n\n return id;\n}\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @function b2CreateCircleShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing properties like friction and density\n * @param {b2Circle} circle - The circle geometry definition\n * @returns {b2ShapeId} The identifier of the created circle shape\n */\nexport function b2CreateCircleShape(bodyId, def, circle)\n{\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n}\n\n/**\n * @function b2CreateCapsuleShape\n * @summary Creates either a capsule shape or circle shape based on the distance between centers\n * @param {b2BodyId} bodyId - The body ID to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Capsule} capsule - The capsule geometry containing center1, center2 and radius\n * @returns {b2ShapeId} The ID of the created shape\n * @description\n * Creates a capsule shape if the distance between centers is greater than b2_linearSlop.\n * If centers are closer than b2_linearSlop, creates a circle shape instead with radius\n * equal to the capsule radius and center at the midpoint between capsule centers.\n */\nexport function b2CreateCapsuleShape(bodyId, def, capsule)\n{\n const lengthSqr = b2DistanceSquared(capsule.center1, capsule.center2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n const circle = new b2Circle();\n circle.center = b2Lerp(capsule.center1, capsule.center2, 0.5);\n circle.radius = capsule.radius;\n\n return b2CreateShape(bodyId, def, circle, b2ShapeType.b2_circleShape);\n }\n\n return b2CreateShape(bodyId, def, capsule, b2ShapeType.b2_capsuleShape);\n}\n\n/**\n * Creates a polygon shape and attaches it to a body.\n * @function b2CreatePolygonShape\n * @param {b2BodyId} bodyId - The identifier of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition containing common shape properties\n * @param {b2Polygon} polygon - The polygon data including vertices and radius\n * @returns {b2ShapeId} The identifier of the created polygon shape\n * @throws {Error} Throws an assertion error if the polygon radius is invalid or negative\n */\nexport function b2CreatePolygonShape(bodyId, def, polygon)\n{\n console.assert(b2IsValid(polygon.radius) && polygon.radius >= 0.0);\n\n return b2CreateShape(bodyId, def, polygon, b2ShapeType.b2_polygonShape);\n}\n\n/**\n * @summary Creates a segment shape attached to a body\n * @function b2CreateSegmentShape\n * @param {b2BodyId} bodyId - The ID of the body to attach the shape to\n * @param {b2ShapeDef} def - The shape definition parameters\n * @param {b2Segment} segment - The segment geometry defined by point1 and point2\n * @returns {b2ShapeId} The ID of the created segment shape\n * @description\n * Creates a segment shape between two points and attaches it to the specified body.\n * The function validates that the segment length is greater than b2_linearSlop\n * before creating the shape.\n * @throws {Error} Throws an assertion error if the segment length squared is less\n * than or equal to b2_linearSlop squared\n */\nexport function b2CreateSegmentShape(bodyId, def, segment)\n{\n const lengthSqr = b2DistanceSquared(segment.point1, segment.point2);\n\n if (lengthSqr <= b2_linearSlop * b2_linearSlop)\n {\n console.assert(false);\n\n return new b2ShapeId();\n }\n\n return b2CreateShape(bodyId, def, segment, b2ShapeType.b2_segmentShape);\n}\n\nfunction b2DestroyShapeInternal(world, shape, body, wakeBodies)\n{\n const shapeId = shape.id;\n\n if (shape.prevShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.prevShapeId);\n world.shapeArray[shape.prevShapeId].nextShapeId = shape.nextShapeId;\n }\n\n if (shape.nextShapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.shapeArray, shape.nextShapeId);\n world.shapeArray[shape.nextShapeId].prevShapeId = shape.prevShapeId;\n }\n\n if (shapeId === body.headShapeId)\n {\n body.headShapeId = shape.nextShapeId;\n }\n\n body.shapeCount -= 1;\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyShape\n * @summary Destroys a shape in the physics world and updates the parent body's mass if needed.\n * @param {b2ShapeId} shapeId - The identifier of the shape to destroy.\n * @description\n * Removes a shape from the physics world. If the parent body has automatic mass calculation enabled,\n * the body's mass properties are recalculated after the shape is destroyed.\n * The function performs the following operations:\n * 1. Retrieves the world and shape from the provided shapeId\n * 2. Destroys the shape internally\n * 3. Updates the parent body's mass data if automatic mass calculation is enabled\n */\nexport function b2DestroyShape(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n const id = shapeId.index1 - 1;\n\n // b2CheckIdAndRevision(world.shapeArray, id, shapeId.revision);\n\n const shape = world.shapeArray[id];\n\n const wakeBodies = true;\n\n const body = b2GetBody(world, shape.bodyId);\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n\n if (body.updateBodyMass === true)\n {\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2CreateChain\n * @description Creates a chain shape composed of connected line segments attached to a body.\n * The chain can be either a closed loop or an open chain.\n * @param {b2BodyId} bodyId - The ID of the body to attach the chain to\n * @param {b2ChainDef} def - The chain definition containing:\n * - {number} count - Number of vertices (must be >= 4)\n * - {b2Vec2[]} points - Array of vertex points\n * - {boolean} isLoop - Whether the chain forms a closed loop\n * - {number} friction - Friction coefficient (must be >= 0)\n * - {number} restitution - Restitution coefficient (must be >= 0)\n * - {b2Filter} filter - Collision filter data\n * - {*} userData - User data pointer\n * @returns {b2ChainId} The ID of the created chain shape\n * @throws {Error} Throws assertion error if friction or restitution are invalid/negative,\n * or if count is less than 4\n */\nexport function b2CreateChain(bodyId, def)\n{\n // b2CheckDef(def);\n console.assert(b2IsValid(def.friction) && def.friction >= 0.0);\n console.assert(b2IsValid(def.restitution) && def.restitution >= 0.0);\n console.assert(def.count >= 4);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2ChainId();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const chainId = b2AllocId(world.chainIdPool);\n\n if (chainId === world.chainArray.length)\n {\n world.chainArray.push(new b2ChainShape());\n }\n\n // b2CheckIndex(world.chainArray, chainId);\n const chainShape = world.chainArray[chainId];\n\n chainShape.id = chainId;\n chainShape.bodyId = body.id;\n chainShape.nextChainId = body.headChainId;\n chainShape.revision += 1;\n body.headChainId = chainId;\n\n const shapeDef = b2DefaultShapeDef();\n shapeDef.userData = def.userData;\n shapeDef.restitution = def.restitution;\n shapeDef.friction = def.friction;\n shapeDef.filter = def.filter;\n shapeDef.enableContactEvents = false;\n shapeDef.enableHitEvents = false;\n shapeDef.enableSensorEvents = false;\n\n const n = def.count;\n const points = def.points;\n let chainSegment;\n\n if (def.isLoop)\n {\n chainShape.count = n;\n chainShape.shapeIndices = new Array(n);\n\n let prevIndex = n - 1;\n\n for (let i = 0; i < n - 2; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[prevIndex].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i].clone();\n chainSegment.segment.point2 = points[i + 1].clone();\n chainSegment.ghost2 = points[i + 2].clone();\n chainSegment.chainId = chainId;\n prevIndex = i;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 3].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 2].clone();\n chainSegment.segment.point2 = points[n - 1].clone();\n chainSegment.ghost2 = points[0].clone();\n chainSegment.chainId = chainId;\n let shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 2] = shape.id;\n\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[n - 2].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[n - 1].clone();\n chainSegment.segment.point2 = points[0].clone();\n chainSegment.ghost2 = points[1].clone();\n chainSegment.chainId = chainId;\n shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[n - 1] = shape.id;\n }\n else\n {\n chainShape.count = n - 3;\n chainShape.shapeIndices = new Array(n);\n\n for (let i = 0; i < n - 3; ++i)\n {\n chainSegment = new b2ChainSegment();\n chainSegment.ghost1 = points[i].clone();\n chainSegment.segment = new b2Segment();\n chainSegment.segment.point1 = points[i + 1].clone();\n chainSegment.segment.point2 = points[i + 2].clone();\n chainSegment.ghost2 = points[i + 3].clone();\n chainSegment.chainId = chainId;\n\n const shape = b2CreateShapeInternal(world, body, transform, shapeDef, chainSegment, b2ShapeType.b2_chainSegmentShape);\n chainShape.shapeIndices[i] = shape.id;\n }\n }\n\n const id = new b2ChainId(chainId + 1, world.worldId, chainShape.revision);\n\n return id;\n}\n\n/**\n * @function b2DestroyChain\n * @description\n * Destroys a chain of shapes attached to a body in a Box2D world. The function removes all shapes\n * associated with the chain and frees the chain ID from the world's chain ID pool.\n * @param {b2ChainId} chainId - The identifier for the chain to be destroyed, containing world and index information\n * @returns {void}\n * @throws {Error} Throws an assertion error if the chain is not found in the body's chain list\n */\nexport function b2DestroyChain(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n const id = chainId.index1 - 1;\n\n // b2CheckIdAndRevision(world.chainArray, id, chainId.revision);\n\n const chain = world.chainArray[id];\n const wakeBodies = true;\n\n const body = b2GetBody(world, chain.bodyId);\n\n // Remove the chain from the body's singly linked list.\n let chainIdPtr = body.headChainId;\n let found = false;\n\n while (chainIdPtr !== null)\n {\n if (chainIdPtr === chain.id)\n {\n // chainIdPtr = chain.nextChainId; // PJB - it's in the C but removed to prevent lint \"no-useless-assignment\"\n found = true;\n\n break;\n }\n\n chainIdPtr = world.chainArray[chainIdPtr].nextChainId;\n }\n\n console.assert(found === true);\n\n if (found === false)\n {\n return;\n }\n\n const count = chain.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chain.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n b2DestroyShapeInternal(world, shape, body, wakeBodies);\n }\n\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, id);\n chain.id = null;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2ComputeShapeAABB(shape, xf)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleAABB(shape.capsule, xf);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleAABB(shape.circle, xf);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonAABB(shape.polygon, xf);\n\n case b2ShapeType.b2_segmentShape:\n return b2ComputeSegmentAABB(shape.segment, xf);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2ComputeSegmentAABB(shape.chainSegment.segment, xf);\n\n default:\n console.assert(false);\n\n return new b2AABB(xf.p.x, xf.p.y, xf.p.x, xf.p.y);\n }\n}\n\nexport function b2GetShapeCentroid(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2Lerp(shape.capsule.center1, shape.capsule.center2, 0.5);\n\n case b2ShapeType.b2_circleShape:\n return shape.circle.center.clone();\n\n case b2ShapeType.b2_polygonShape:\n return shape.polygon.centroid.clone();\n\n case b2ShapeType.b2_segmentShape:\n return b2Lerp(shape.segment.point1, shape.segment.point2, 0.5);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2Lerp(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2, 0.5);\n\n default:\n return new b2Vec2(0, 0);\n }\n}\n\nexport function b2GetShapePerimeter(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return 2.0 * b2Length(b2Sub(shape.capsule.center1, shape.capsule.center2)) +\n 2.0 * Math.PI * shape.capsule.radius;\n\n case b2ShapeType.b2_circleShape:\n return 2.0 * Math.PI * shape.circle.radius;\n\n case b2ShapeType.b2_polygonShape:\n {\n const points = shape.polygon.vertices;\n const count = shape.polygon.count;\n let perimeter = 2.0 * Math.PI * shape.polygon.radius;\n console.assert(count > 0);\n let prev = points[count - 1];\n\n for (let i = 0; i < count; ++i)\n {\n const next = points[i];\n perimeter += b2Length(b2Sub(next, prev));\n prev = next;\n }\n\n return perimeter;\n }\n\n case b2ShapeType.b2_segmentShape:\n return 2.0 * b2Length(b2Sub(shape.segment.point1, shape.segment.point2));\n\n case b2ShapeType.b2_chainSegmentShape:\n return 2.0 * b2Length(b2Sub(shape.chainSegment.segment.point1, shape.chainSegment.segment.point2));\n\n default:\n return 0.0;\n }\n}\n\nexport function b2ComputeShapeMass(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2ComputeCapsuleMass(shape.capsule, shape.density);\n\n case b2ShapeType.b2_circleShape:\n return b2ComputeCircleMass(shape.circle, shape.density);\n\n case b2ShapeType.b2_polygonShape:\n return b2ComputePolygonMass(shape.polygon, shape.density);\n\n default:\n return new b2MassData();\n }\n}\n\nexport function b2ComputeShapeExtent(shape, localCenter)\n{\n const extent = new b2ShapeExtent();\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const radius = shape.capsule.radius;\n extent.minExtent = radius;\n const c1 = b2Sub(shape.capsule.center1, localCenter);\n const c2 = b2Sub(shape.capsule.center2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2))) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const radius = shape.circle.radius;\n extent.minExtent = radius;\n extent.maxExtent = b2Length(b2Sub(shape.circle.center, localCenter)) + radius;\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n let minExtent = Number.MAX_VALUE;\n let maxExtentSqr = 0.0;\n const count = poly.count;\n\n for (let i = 0; i < count; ++i)\n {\n const v = poly.vertices[i];\n const planeOffset = b2Dot(poly.normals[i], b2Sub(v, poly.centroid));\n minExtent = Math.min(minExtent, planeOffset);\n\n const distanceSqr = b2LengthSquared(b2Sub(v, localCenter));\n maxExtentSqr = Math.max(maxExtentSqr, distanceSqr);\n }\n\n extent.minExtent = minExtent + poly.radius;\n extent.maxExtent = Math.sqrt(maxExtentSqr) + poly.radius;\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.segment.point1, localCenter);\n const c2 = b2Sub(shape.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n extent.minExtent = 0.0;\n const c1 = b2Sub(shape.chainSegment.segment.point1, localCenter);\n const c2 = b2Sub(shape.chainSegment.segment.point2, localCenter);\n extent.maxExtent = Math.sqrt(Math.max(b2LengthSquared(c1), b2LengthSquared(c2)));\n }\n\n break;\n\n default:\n break;\n }\n\n return extent;\n}\n\nconst rayPoint = new b2Vec2(0, 0);\nconst rayNormal = new b2Vec2(0, 1);\n\nexport function b2RayCastShape(input, shape, transform)\n{\n const localInput = input;\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2ShapeCastShape(input, shape, transform)\n{\n const localInput = input;\n\n for (let i = 0; i < localInput.count; ++i)\n {\n localInput.points[i] = b2InvTransformPoint(transform, input.points[i]);\n }\n\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n\n let output = new b2CastOutput();\n output.hit = false;\n output.fraction = 0.0;\n output.normal = new b2Vec2(0, 0);\n output.point = new b2Vec2(0, 0);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2ShapeCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2ShapeCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2ShapeCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2ShapeCastSegment(localInput, shape.segment);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2ShapeCastSegment(localInput, shape.chainSegment.segment);\n\n break;\n\n default:\n return output;\n }\n\n output.point = b2TransformPoint(transform, output.point);\n output.normal = b2RotateVector(transform.q, output.normal);\n\n return output;\n}\n\nexport function b2CreateShapeProxy(shape, bp, type, transform, forcePairCreation)\n{\n console.assert(shape.proxyKey == B2_NULL_INDEX);\n\n b2UpdateShapeAABBs(shape, transform, type);\n\n // Create proxies in the broad-phase.\n shape.proxyKey = b2BroadPhase_CreateProxy(bp, type, shape.fatAABB, shape.filter.categoryBits, shape.id, forcePairCreation);\n console.assert(B2_PROXY_TYPE(shape.proxyKey) < b2BodyType.b2_bodyTypeCount);\n}\n\nexport function b2DestroyShapeProxy(shape, bp)\n{\n if (shape.proxyKey != B2_NULL_INDEX)\n {\n b2BroadPhase_DestroyProxy(bp, shape.proxyKey);\n shape.proxyKey = B2_NULL_INDEX;\n }\n}\n\nexport function b2MakeShapeDistanceProxy(shape)\n{\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2MakeProxy([ shape.capsule.center1.clone(), shape.capsule.center2.clone() ], 2, shape.capsule.radius);\n\n case b2ShapeType.b2_circleShape:\n return b2MakeProxy([ shape.circle.center.clone() ], 1, shape.circle.radius);\n\n case b2ShapeType.b2_polygonShape:\n return b2MakeProxy(shape.polygon.vertices, shape.polygon.count, shape.polygon.radius);\n\n case b2ShapeType.b2_segmentShape:\n return b2MakeProxy([ shape.segment.point1, shape.segment.point2 ], 2, 0.0);\n\n case b2ShapeType.b2_chainSegmentShape:\n return b2MakeProxy([ shape.chainSegment.segment.point1.clone(), shape.chainSegment.segment.point2.clone() ], 2, 0.0);\n\n default:\n console.assert(false);\n\n return new b2DistanceProxy();\n }\n}\n\n/**\n * @function b2Shape_GetBody\n * @summary Gets the body ID associated with a given shape ID.\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2BodyId} The ID of the body that owns the shape.\n * @description\n * Retrieves the body ID for a given shape by first accessing the world object,\n * then getting the shape from the world, and finally creating a body ID\n * from the shape's stored body reference.\n */\nexport function b2Shape_GetBody(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return b2MakeBodyId(world, shape.bodyId);\n}\n\n// \n/**\n * @function b2Shape_GetWorld\n * @summary Get the world that owns this shape\n * @param {b2ShapeId} shapeId - The ID of the shape to query.\n * @returns {b2WorldId} The ID of the world that owns the shape.\n */\nexport function b2Shape_GetWorld(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n return new b2WorldId(shapeId.world0 + 1, world.revision);\n}\n\n/**\n * @summary Sets the user data associated with a shape.\n * @function b2Shape_SetUserData\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {*} userData - The user data to associate with the shape.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a shape identified by shapeId. The shape must exist\n * in the world referenced by the shapeId. The function retrieves the shape from the world\n * and updates its userData property.\n */\nexport function b2Shape_SetUserData(shapeId, userData)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n shape.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a shape.\n * @function b2Shape_GetUserData\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {void} The user data associated with the shape.\n * @description\n * This function retrieves the user data that was previously attached to a shape\n * by looking up the shape in the world using the provided shape ID.\n */\nexport function b2Shape_GetUserData(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.userData;\n}\n\n/**\n * Checks if a shape is marked as a sensor.\n * @function b2Shape_IsSensor\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if the shape is a sensor, false otherwise.\n * @description\n * Retrieves a shape from the physics world using its ID and returns\n * whether it is configured as a sensor. Sensor shapes detect collisions\n * but do not generate physical responses.\n */\nexport function b2Shape_IsSensor(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.isSensor;\n}\n\n/**\n * Tests if a point lies within a shape.\n * @function b2Shape_TestPoint\n * @param {b2ShapeId} shapeId - The identifier for the shape to test against\n * @param {b2Vec2} point - The world space point to test\n * @returns {boolean} True if the point is inside the shape, false otherwise\n * @description\n * Transforms the test point into the shape's local space and performs\n * point-in-shape testing based on the shape type (capsule, circle, or polygon).\n * Returns false for unrecognized shape types.\n */\nexport function b2Shape_TestPoint(shapeId, point)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n const localPoint = b2InvTransformPoint(transform, point);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n return b2PointInCapsule(localPoint, shape.capsule);\n\n case b2ShapeType.b2_circleShape:\n return b2PointInCircle(localPoint, shape.circle);\n\n case b2ShapeType.b2_polygonShape:\n return b2PointInPolygon(localPoint, shape.polygon);\n\n default:\n return false;\n }\n}\n\n\n/**\n * @function b2Shape_RayCast\n * @description\n * Performs a ray cast against a shape in world space, transforming the input/output\n * between local and world coordinates.\n * @param {b2ShapeId} shapeId - The identifier for the shape to test\n * @param {b2RayCastInput} input - The ray to cast, in world coordinates\n * @returns {b2CastOutput} The ray cast results containing:\n * - hit: boolean indicating if the ray intersects the shape\n * - point: intersection point in world coordinates (if hit is true)\n * - normal: surface normal at intersection in world coordinates (if hit is true)\n * - fraction: fraction of translation where intersection occurs (if hit is true)\n * @throws {Error} Throws assertion error if shape type is invalid\n */\nexport function b2Shape_RayCast(shapeId, input)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n const transform = b2GetBodyTransform(world, shape.bodyId);\n\n // input in local coordinates\n const localInput = new b2RayCastInput();\n localInput.origin = b2InvTransformPoint(transform, input.origin);\n localInput.translation = b2InvRotateVector(transform.q, input.translation);\n localInput.maxFraction = input.maxFraction;\n\n\n let output = new b2CastOutput(rayNormal, rayPoint);\n\n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n output = b2RayCastCapsule(localInput, shape.capsule);\n\n break;\n\n case b2ShapeType.b2_circleShape:\n output = b2RayCastCircle(localInput, shape.circle);\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n output = b2RayCastSegment(localInput, shape.segment, false);\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n output = b2RayCastPolygon(localInput, shape.polygon);\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n output = b2RayCastSegment(localInput, shape.chainSegment.segment, true);\n\n break;\n\n default:\n console.assert(false);\n\n return output;\n }\n\n if (output.hit)\n {\n // convert to world coordinates\n output.normal = b2RotateVector(transform.q, output.normal);\n output.point = b2TransformPoint(transform, output.point);\n }\n\n return output;\n}\n\n\n/**\n * @function b2Shape_SetDensity\n * @summary Sets the density of a shape and optionally updates the parent body's mass.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {number} density - The new density value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets a new density value for the specified shape. If the new density matches\n * the current density, no changes are made. The function performs validation\n * to ensure the density is a valid non-negative number.\n * @throws {Error} Throws an assertion error if the density is invalid or negative.\n */\nexport function b2Shape_SetDensity(shapeId, density)\n{\n console.assert(b2IsValid(density) && density >= 0.0);\n\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world == null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (density == shape.density)\n {\n // early return to avoid expensive function\n return;\n }\n\n shape.density = density;\n}\n\n/**\n * @summary Gets the density value of a shape.\n * @function b2Shape_GetDensity\n * @param {b2ShapeId} shapeId - The identifier for the shape within a Box2D world.\n * @returns {number} The density value of the specified shape.\n * @description\n * Retrieves the density property of a shape by first accessing the world object\n * using the world identifier stored in the shapeId, then accessing the specific\n * shape within that world.\n */\nexport function b2Shape_GetDensity(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.density;\n}\n\n/**\n * Sets the friction coefficient for a shape.\n * @function b2Shape_SetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify\n * @param {number} friction - The friction coefficient value (must be >= 0)\n * @returns {void}\n * @throws {Error} Throws an assertion error if friction is invalid or negative\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Sets a new friction value for the specified shape. The operation will not proceed\n * if the physics world is locked. The friction parameter must be a valid number\n * greater than or equal to zero.\n */\nexport function b2Shape_SetFriction(shapeId, friction)\n{\n console.assert(b2IsValid(friction) && friction >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.friction = friction;\n}\n\n/**\n * Gets the friction coefficient of a shape.\n * @function b2Shape_GetFriction\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The friction coefficient of the shape.\n * @description\n * Retrieves the friction value from a shape object in the Box2D physics world\n * using the provided shape identifier.\n */\nexport function b2Shape_GetFriction(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.friction;\n}\n\n/**\n * Sets the restitution (bounciness) value for a shape.\n * @function b2Shape_SetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {number} restitution - The restitution value to set. Must be non-negative.\n * @returns {void}\n * @throws {Error} Throws an assertion error if restitution is invalid or negative,\n * or if the world is locked.\n */\nexport function b2Shape_SetRestitution(shapeId, restitution)\n{\n console.assert(b2IsValid(restitution) && restitution >= 0.0);\n\n const world = b2GetWorld(shapeId.world0);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.restitution = restitution;\n}\n\n/**\n * Gets the restitution coefficient of a shape.\n * @function b2Shape_GetRestitution\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world.\n * @returns {number} The restitution coefficient of the shape.\n * @description\n * Retrieves the restitution (bounciness) value associated with the specified shape\n * from the physics world.\n */\nexport function b2Shape_GetRestitution(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.restitution;\n}\n\n/**\n * Gets the filter data for a shape.\n * @function b2Shape_GetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2Filter} The collision filter data associated with the shape.\n * @description\n * Retrieves the collision filtering data from a shape by first accessing the world\n * object using the world identifier stored in the shapeId, then accessing the\n * shape within that world using the shapeId.\n */\nexport function b2Shape_GetFilter(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.filter;\n}\n\n// Static function, not exported\nfunction b2ResetProxy(world, shape, wakeBodies, destroyProxy)\n{\n const body = b2GetBody(world, shape.bodyId);\n\n const shapeId = shape.id;\n\n // destroy all contacts associated with this shape\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.shapeIdA === shapeId || contact.shapeIdB === shapeId)\n {\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n b2UpdateShapeAABBs(shape, transform, proxyType);\n\n if (destroyProxy)\n {\n b2BroadPhase_DestroyProxy(world.broadPhase, shape.proxyKey);\n\n const forcePairCreation = true;\n shape.proxyKey = b2BroadPhase_CreateProxy(world.broadPhase, proxyType, shape.fatAABB, shape.filter.categoryBits,\n shapeId, forcePairCreation);\n }\n else\n {\n b2BroadPhase_MoveProxy(world.broadPhase, shape.proxyKey, shape.fatAABB);\n }\n }\n else\n {\n const proxyType = body.type;\n b2UpdateShapeAABBs(shape, transform, proxyType);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Sets the collision filter for a shape.\n * @function b2Shape_SetFilter\n * @param {b2ShapeId} shapeId - The identifier for the shape to modify.\n * @param {b2Filter} filter - The new collision filter settings to apply.\n * @returns {void}\n * @description\n * Updates the collision filter properties of a shape. If the new filter settings\n * match the existing ones, no changes are made. When the categoryBits change,\n * the shape's broad-phase proxy is destroyed and recreated. The function also\n * wakes connected bodies when the filter changes.\n */\nexport function b2Shape_SetFilter(shapeId, filter)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (filter.maskBits === shape.filter.maskBits && filter.categoryBits === shape.filter.categoryBits &&\n filter.groupIndex === shape.filter.groupIndex)\n {\n return;\n }\n\n // If the category bits change, I need to destroy the proxy because it affects the tree sorting.\n const destroyProxy = filter.categoryBits === shape.filter.categoryBits;\n\n shape.filter = filter;\n\n // need to wake bodies because a filter change may destroy contacts\n const wakeBodies = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_EnableSensorEvents\n * @summary Enables or disables sensor events for a specific shape.\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable sensor events, false to disable them.\n * @returns {void}\n * @description\n * Sets the enableSensorEvents property of a shape in the physics world. The shape\n * must exist in a valid world context for the operation to succeed.\n */\nexport function b2Shape_EnableSensorEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableSensorEvents = flag;\n}\n\n/**\n * Checks if sensor events are enabled for a given shape.\n * @function b2Shape_AreSensorEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if sensor events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and returns\n * the state of its sensor events flag.\n */\nexport function b2Shape_AreSensorEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableSensorEvents;\n}\n\n/**\n * @summary Enables or disables contact events for a shape.\n * @function b2Shape_EnableContactEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @param {boolean} flag - True to enable contact events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate contact events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n */\nexport function b2Shape_EnableContactEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableContactEvents = flag;\n}\n\n/**\n * Checks if contact events are enabled for a given shape.\n * @function b2Shape_AreContactEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if contact events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enableContactEvents property of that shape.\n */\nexport function b2Shape_AreContactEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableContactEvents;\n}\n\n/**\n * @function b2Shape_EnablePreSolveEvents\n * @param {b2ShapeId} shapeId - The identifier for the shape in the physics world\n * @param {boolean} flag - Boolean value to enable or disable pre-solve events for the shape\n * @returns {void}\n * @description\n * Enables or disables pre-solve events for a specific shape in the physics simulation.\n * The function first validates the world reference and returns if invalid.\n * If valid, it updates the shape's pre-solve events setting according to the flag parameter.\n */\nexport function b2Shape_EnablePreSolveEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enablePreSolveEvents = flag;\n}\n\n/**\n * @summary Checks if pre-solve events are enabled for a given shape.\n * @function b2Shape_ArePreSolveEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if pre-solve events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * the enablePreSolveEvents property of that shape.\n */\nexport function b2Shape_ArePreSolveEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enablePreSolveEvents;\n}\n\n/**\n * @summary Enables or disables hit event notifications for a shape.\n * @function b2Shape_EnableHitEvents\n * @param {b2ShapeId} shapeId - The identifier of the shape to modify.\n * @param {boolean} flag - True to enable hit events, false to disable.\n * @returns {void}\n * @description\n * Sets whether a shape should generate hit events during collision detection.\n * The shape must belong to a valid world, otherwise the function returns without effect.\n * @throws {Error} If the world associated with the shapeId is locked.\n */\nexport function b2Shape_EnableHitEvents(shapeId, flag)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.enableHitEvents = flag;\n}\n\n/**\n * Checks if hit events are enabled for a given shape.\n * @function b2Shape_AreHitEventsEnabled\n * @param {b2ShapeId} shapeId - The identifier for the shape to check.\n * @returns {boolean} True if hit events are enabled for the shape, false otherwise.\n * @description\n * This function retrieves a shape from the physics world using its ID and checks\n * if hit events are enabled for that shape by accessing the enableHitEvents property.\n */\nexport function b2Shape_AreHitEventsEnabled(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.enableHitEvents;\n}\n\n/**\n * Gets the type of a shape from the physics world using its shape ID.\n * @function b2Shape_GetType\n * @param {b2ShapeId} shapeId - The ID of the shape to query\n * @returns {b2ShapeType} The type of the specified shape\n * @description\n * Retrieves a shape from the physics world using the provided shape ID\n * and returns its type classification.\n */\nexport function b2Shape_GetType(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n return shape.type;\n}\n\n/**\n * @function b2Shape_GetCircle\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Circle} The circle shape object\n * @description\n * Retrieves a circle shape from the physics world using the provided shape identifier.\n * @throws {Error} Throws an assertion error if the shape type is not b2_circleShape\n */\nexport function b2Shape_GetCircle(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_circleShape);\n\n return shape.circle;\n}\n\n/**\n * @function b2Shape_GetSegment\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference\n * @returns {b2Segment} The segment data from the specified shape\n * @description\n * Retrieves the segment data from a shape in the physics world. The shape must be of type b2_segmentShape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_segmentShape\n */\nexport function b2Shape_GetSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_segmentShape);\n\n return shape.segment;\n}\n\n/**\n * Gets the chain segment data from a shape identified by its ID.\n * @function b2Shape_GetChainSegment\n * @param {Object} shapeId - An object containing the shape identifier and world reference.\n * @param {number} shapeId.world0 - The world identifier.\n * @returns {Object} The chain segment data associated with the shape.\n * @throws {Error} Throws an assertion error if the shape type is not b2_chainSegmentShape.\n */\nexport function b2Shape_GetChainSegment(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_chainSegmentShape);\n\n return shape.chainSegment;\n}\n\n/**\n * @function b2Shape_GetCapsule\n * @param {b2ShapeId} shapeId - A shape identifier containing world and shape reference information\n * @returns {b2Capsule} The capsule shape data associated with the given shape ID\n * @description\n * Retrieves the capsule shape data from a shape in the physics world using the provided shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_capsuleShape\n */\nexport function b2Shape_GetCapsule(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_capsuleShape);\n\n return shape.capsule;\n}\n\n/**\n * Gets a polygon shape from a shape ID.\n * @function b2Shape_GetPolygon\n * @param {b2ShapeId} shapeId - The ID of the shape to retrieve.\n * @returns {b2Polygon} The polygon shape associated with the given shape ID.\n * @throws {Error} Throws an assertion error if the shape type is not b2_polygonShape.\n */\nexport function b2Shape_GetPolygon(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n console.assert(shape.type === b2ShapeType.b2_polygonShape);\n\n return shape.polygon;\n}\n\n/**\n * @function b2Shape_SetCircle\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Circle} circle - The circle shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to circle and updates its properties. The function updates\n * the shape's proxy in the broad-phase collision system and can wake connected bodies.\n * If the world is locked or invalid, the function returns without making changes.\n */\nexport function b2Shape_SetCircle(shapeId, circle)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.circle = circle;\n shape.type = b2ShapeType.b2_circleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetCapsule\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Capsule} capsule - The capsule shape configuration to set\n * @returns {void}\n * @description\n * Sets a shape's type to capsule and updates its configuration. The function\n * resets the shape's proxy in the broad-phase collision system, optionally\n * waking connected bodies and destroying the existing proxy.\n * @throws {Error} If the world reference is invalid (null)\n */\nexport function b2Shape_SetCapsule(shapeId, capsule)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.capsule = capsule;\n shape.type = b2ShapeType.b2_capsuleShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetSegment\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Segment} segment - The segment data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to segment and updates its segment data. After updating,\n * it resets the shape's collision proxy in the physics world. The function requires\n * a valid world lock to execute successfully.\n */\nexport function b2Shape_SetSegment(shapeId, segment)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.segment = segment;\n shape.type = b2ShapeType.b2_segmentShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_SetPolygon\n * @param {b2ShapeId} shapeId - The identifier for the shape to be modified\n * @param {b2Polygon} polygon - The polygon data to assign to the shape\n * @returns {void}\n * @description\n * Sets a shape's type to polygon and assigns polygon data to it. The function\n * updates the shape's proxy in the broad-phase collision system and can wake\n * connected bodies.\n * @throws {Error} If the world associated with the shapeId is not found\n */\nexport function b2Shape_SetPolygon(shapeId, polygon)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const shape = b2GetShape(world, shapeId);\n shape.polygon = polygon;\n shape.type = b2ShapeType.b2_polygonShape;\n\n // need to wake bodies so they can react to the shape change\n const wakeBodies = true;\n const destroyProxy = true;\n b2ResetProxy(world, shape, wakeBodies, destroyProxy);\n}\n\n/**\n * @function b2Shape_GetParentChain\n * @param {b2ShapeId} shapeId - The identifier of the shape to check for parent chain\n * @returns {b2ChainId} A b2ChainId object. Returns an empty b2ChainId (default values) if the shape\n * is not a chain segment shape or has no parent chain\n * @description\n * Retrieves the parent chain identifier for a given shape if it is a chain segment shape\n * and has an associated chain. The function checks if the shape is of type b2_chainSegmentShape\n * and has a valid chain reference before returning the chain identifier.\n */\nexport function b2Shape_GetParentChain(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n const shape = b2GetShape(world, shapeId);\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const chainId = shape.chainSegment.chainId;\n\n if (chainId !== B2_NULL_INDEX)\n {\n // b2CheckId(world.chainArray, chainId);\n const chain = world.chainArray[chainId];\n\n return new b2ChainId(chainId + 1, shapeId.world0, chain.revision);\n }\n }\n\n return new b2ChainId();\n}\n\n\n/**\n * Get the world that owns this chain shape\n * @function b2Chain_GetWorld\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {b2WorldId}\n */\nexport function b2Chain_GetWorld(chainId)\n{\n const world = b2GetWorld(chainId.world0);\n\n return new b2WorldId(chainId.world0 + 1, world.revision);\n}\n\n\n/**\n * Get the number of segments on this chain.\n * @function b2Chain_GetSegmentCount\n * @param {b2ChainId} chainId - The identifier for the chain\n * @returns {number}\n */\nexport function b2Chain_GetSegmentCount(chainId)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n\n return chainShape.count;\n}\n\n\n/**\n * Fill a user array with chain segment shape ids up to the specified capacity. \n * @function b2Chain_GetSegments\n * @param {b2ChainId} chainId - The identifier for the chain\n * @param {b2ShapeId} segmentArray - list of segment shapes for this chain\n * @param {number} capacity - \n * @returns {number} The actual number of segments returned.\n */\nexport function b2Chain_GetSegments(chainId, segmentArray, capacity)\n{\n const world = b2GetWorldLocked(chainId.world0);\n const chainShape = b2GetChainShape(world, chainId);\n const count = Math.min(chainShape.count, capacity);\n\n for (let i=0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n const shape = world.shapeArray[shapeId];\n segmentArray[i] = new b2ShapeId(shapeId + 1, chainId.world0, shape.revision);\n }\n\n return count;\n}\n\n\n/**\n * Sets the friction value for all shapes in a chain.\n * @function b2Chain_SetFriction\n * @param {b2ChainId} chainId - The identifier for the chain whose friction will be modified\n * @param {number} friction - The friction value to set for all shapes in the chain\n * @returns {void}\n * @description\n * Updates the friction property of each shape within the specified chain. The function\n * retrieves the chain shape from the world, then iterates through all shapes in the\n * chain and sets their friction to the specified value.\n */\nexport function b2Chain_SetFriction(chainId, friction)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.friction = friction;\n }\n}\n\n/**\n * @function b2Chain_SetRestitution\n * @summary Sets the restitution value for all shapes in a chain.\n * @param {b2ChainId} chainId - The identifier for the chain whose restitution will be set\n * @param {number} restitution - The restitution value to apply to all shapes in the chain\n * @returns {void}\n * @description\n * Sets the restitution coefficient for all shapes that make up the specified chain.\n * If the world is not found using the provided chainId, the function returns without making changes.\n */\nexport function b2Chain_SetRestitution(chainId, restitution)\n{\n const world = b2GetWorldLocked(chainId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const chainShape = b2GetChainShape(world, chainId);\n\n const count = chainShape.count;\n\n for (let i = 0; i < count; ++i)\n {\n const shapeId = chainShape.shapeIndices[i];\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n shape.restitution = restitution;\n }\n}\n\n/**\n * Gets the contact capacity for a given shape.\n * @function b2Shape_GetContactCapacity\n * @param {b2ShapeId} shapeId - The identifier for the shape to check\n * @returns {number} The number of contacts for the shape's body. Returns 0 if the world is invalid,\n * or if the shape is a sensor.\n * @description\n * Retrieves the number of contacts associated with the body that owns the specified shape.\n * If the shape is a sensor or the world reference is invalid, the function returns 0.\n */\nexport function b2Shape_GetContactCapacity(shapeId)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Shape_GetContactData\n * @param {b2ShapeId} shapeId - The identifier of the shape to get contact data for\n * @param {Array<{shapeIdA: b2ShapeId, shapeIdB: b2ShapeId, manifold: b2Manifold}>} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts found and stored in contactData\n * @description\n * Retrieves contact data for a specified shape. For each valid contact involving the shape,\n * stores the shape IDs of both bodies in contact and their contact manifold.\n * Only stores contacts where the touching flag is set and ignores sensor shapes.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Shape_GetContactData(shapeId, contactData, capacity)\n{\n const world = b2GetWorldLocked(shapeId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const shape = b2GetShape(world, shapeId);\n\n if (shape.isSensor)\n {\n return 0;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Does contact involve this shape and is it touching?\n if ((contact.shapeIdA === shapeId.index1 - 1 || contact.shapeIdB === shapeId.index1 - 1) &&\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, shapeId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, shapeId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Shape_GetAABB\n * @summary Gets the Axis-Aligned Bounding Box (AABB) for a shape.\n * @param {b2ShapeId} shapeId - The identifier for the shape.\n * @returns {b2AABB} The AABB of the shape. Returns an empty AABB if the world is null.\n * @description\n * Retrieves the Axis-Aligned Bounding Box (AABB) associated with a shape in the physics world.\n * If the world reference is invalid, returns a default AABB with zero dimensions.\n */\nexport function b2Shape_GetAABB(shapeId)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const shape = b2GetShape(world, shapeId);\n\n return shape.aabb;\n}\n\n/**\n * @function b2Shape_GetClosestPoint\n * @summary Gets the closest point on a shape to a target point\n * @param {b2ShapeId} shapeId - ID of the shape to query\n * @param {b2Vec2} target - The target point to find the closest point to\n * @returns {b2Vec2} The closest point on the shape to the target point. Returns (0,0) if the world is invalid.\n * @description\n * Calculates the closest point on a shape to a given target point, taking into account\n * the shape's position and rotation in world space. Uses the distance calculation\n * algorithm with shape proxies and transforms.\n */\nexport function b2Shape_GetClosestPoint(shapeId, target)\n{\n const world = b2GetWorld(shapeId.world0);\n\n if (world === null)\n {\n return new b2Vec2(0, 0);\n }\n\n const shape = b2GetShape(world, shapeId);\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ target ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.pointA;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Vec2 } from './math_functions_h.js';\nimport { b2Capsule, b2ChainSegment, b2Circle, b2Polygon, b2Segment } from './collision_h.js';\nimport { b2Filter, b2ShapeType } from './types_h.js';\n\nexport class b2Shape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.prevShapeId = 0;\n this.nextShapeId = 0;\n this.type = b2ShapeType.e_unknown;\n this.density = 0;\n this.friction = 0;\n this.restitution = 0;\n\n this.aabb = new b2AABB();\n this.fatAABB = new b2AABB();\n this.localCentroid = new b2Vec2();\n this.proxyKey = 0;\n\n this.filter = new b2Filter();\n this.userData = null;\n this.customColor = 0;\n\n this.capsule = new b2Capsule();\n this.circle = new b2Circle();\n this.polygon = new b2Polygon();\n this.segment = new b2Segment();\n this.chainSegment = new b2ChainSegment();\n\n this.revision = 0;\n this.isSensor = false;\n this.enableSensorEvents = false;\n this.enableContactEvents = false;\n this.enableHitEvents = false;\n this.enablePreSolveEvents = false;\n this.enlargedAABB = false;\n this.isFast = false;\n\n this.imageNoDebug = false; // suppress debug drawing except when there's an image attached\n this.image = null;\n this.imageScale = null;\n this.imageOffset = null;\n this.imageRect = null; // use a b2AABB with width and height in upperBoundX and upperBoundY\n }\n}\n\nexport class b2ChainShape\n{\n constructor()\n {\n this.id = 0;\n this.bodyId = 0;\n this.nextChainId = 0;\n this.shapeIndices = [];\n this.count = 0;\n this.revision = 0;\n }\n}\n\nexport class b2ShapeExtent\n{\n constructor()\n {\n this.minExtent = 0;\n this.maxExtent = 0;\n }\n}\n\nexport {\n b2CreateCircleShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2CreateSegmentShape,\n b2CreateChain,\n b2DestroyShape,\n b2CreateShapeProxy,\n b2DestroyShapeProxy,\n b2ComputeShapeMass,\n b2ComputeShapeExtent,\n b2ComputeShapeAABB,\n b2GetShapeCentroid,\n b2GetShapePerimeter,\n b2MakeShapeDistanceProxy,\n b2RayCastShape,\n b2ShapeCastShape,\n b2Shape_AreContactEventsEnabled,\n b2Shape_AreHitEventsEnabled,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_EnableHitEvents,\n b2Shape_EnablePreSolveEvents,\n b2Shape_EnableSensorEvents,\n b2Shape_GetAABB,\n b2Shape_GetBody,\n b2Shape_GetWorld,\n b2Shape_GetCapsule,\n b2Shape_GetCircle,\n b2Shape_GetClosestPoint,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetDensity,\n b2Shape_GetFilter,\n b2Shape_GetFriction,\n b2Shape_GetParentChain,\n b2Shape_GetPolygon,\n b2Shape_GetRestitution,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetType,\n b2Shape_GetUserData,\n b2Shape_IsSensor,\n b2Shape_RayCast,\n b2Shape_SetCapsule,\n b2Shape_SetCircle,\n b2Shape_SetDensity,\n b2Shape_SetFilter,\n b2Shape_SetFriction,\n b2Shape_SetPolygon,\n b2Shape_SetRestitution,\n b2Shape_SetSegment,\n b2Shape_SetUserData,\n b2Shape_TestPoint,\n b2Chain_GetWorld,\n b2Chain_GetSegmentCount,\n b2Chain_GetSegments,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain,\n} from '../shape_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BitSet } from './include/bitset_h.js';\n\n/**\n * @namespace BitSet\n */\n\nconst b2_64bits = 8;\n\nexport function b2CreateBitSet(bitCapacity)\n{\n const bitSet = new b2BitSet();\n const cap = Math.floor((bitCapacity + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n bitSet.blockCapacity = cap;\n bitSet.blockCount = 0;\n bitSet.bits = new BigUint64Array(bitSet.blockCapacity);\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2DestroyBitSet(bitSet)\n{\n bitSet.blockCapacity = 0;\n bitSet.blockCount = 0;\n bitSet.bits = null;\n}\n\nexport function b2SetBitCountAndClear(bitSet, bitCount)\n{\n const blockCount = Math.floor((bitCount + b2_64bits * 8 - 1) / (b2_64bits * 8));\n\n if (bitSet.blockCapacity < blockCount)\n {\n b2DestroyBitSet(bitSet);\n const newBitCapacity = bitCount + (bitCount >> 1);\n bitSet = b2CreateBitSet(newBitCapacity);\n }\n\n bitSet.blockCount = blockCount;\n bitSet.bits.fill(0n);\n\n return bitSet;\n}\n\nexport function b2GrowBitSet(bitSet, blockCount)\n{\n console.assert(blockCount > bitSet.blockCount, \"grow is unnecessary here\");\n\n if (blockCount > bitSet.blockCapacity)\n {\n const oldCapacity = bitSet.blockCapacity;\n bitSet.blockCapacity = blockCount + (blockCount >> 1);\n const newBits = new BigUint64Array(bitSet.blockCapacity);\n newBits.fill(0n);\n\n if (bitSet.blockCount > 0)\n {\n newBits.set(bitSet.bits.subarray(0, oldCapacity));\n }\n\n bitSet.bits = newBits;\n }\n\n bitSet.blockCount = blockCount;\n}\n\nexport function b2InPlaceUnion(setA, setB)\n{\n console.assert(setA.blockCount == setB.blockCount);\n const blockCount = setA.blockCount;\n\n for (let i = 0; i < blockCount; ++i)\n {\n setA.bits[i] |= setB.bits[i];\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2CreateBitSet,\n b2DestroyBitSet,\n b2GrowBitSet,\n b2InPlaceUnion,\n b2SetBitCountAndClear\n} from '../bitset_c.js';\n\n// Bit set provides fast operations on large arrays of bits.\nexport class b2BitSet\n{\n constructor()\n {\n this.bits = null;\n this.blockCapacity = 0;\n this.blockCount = 0;\n }\n}\n\nexport {\n b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear, b2GrowBitSet, b2InPlaceUnion\n};\n\nexport function b2SetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n console.assert(blockIndex < bitSet.blockCount);\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2SetBitGrow(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n b2GrowBitSet(bitSet, blockIndex + 1);\n }\n\n bitSet.bits[blockIndex] |= (BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2ClearBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return;\n }\n \n bitSet.bits[blockIndex] &= ~(BigInt(1) << BigInt(bitIndex % 64));\n}\n\nexport function b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2GetBitSetBytes(bitSet)\n{\n return bitSet.blockCapacity * 8; // 8 bytes per 64-bit block\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { b2AddContact, b2AddJoint, b2ContactArray, b2JointArray, b2RemoveContact, b2RemoveJoint } from './include/block_array_h.js';\nimport { b2BitSet, b2ClearBit, b2CreateBitSet, b2DestroyBitSet, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport { b2CheckIndex, b2SetType } from './include/world_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\n\n/**\n * @namespace ConstraintGraph\n */\n\n// JS conversion is not using threads, everything should go into the overflow set for single thread processing\nexport const b2_overflowIndex = b2_graphColorCount - 1;\n\nexport class b2GraphColor\n{\n constructor()\n {\n this.bodySet = new b2BitSet();\n this.contacts = new b2ContactArray();\n this.joints = new b2JointArray();\n this.overflowConstraints = null;\n }\n}\n\nexport class b2ConstraintGraph\n{\n constructor()\n {\n this.colors = [];\n\n for (let i = 0; i < b2_graphColorCount; i++)\n { this.colors.push(new b2GraphColor()); }\n }\n}\n\nexport function b2CreateGraph(graph, bodyCapacity)\n{\n console.assert( b2_graphColorCount >= 2, \"must have at least two constraint graph colors\" );\n console.assert( b2_overflowIndex == b2_graphColorCount - 1, \"bad over flow index\");\n\n graph = new b2ConstraintGraph();\n\n bodyCapacity = Math.max(bodyCapacity, 8);\n\n for (let i = 0; i < b2_overflowIndex; i++)\n {\n const color = graph.colors[i];\n color.bodySet = b2CreateBitSet(bodyCapacity);\n color.bodySet = b2SetBitCountAndClear(color.bodySet, bodyCapacity);\n }\n\n return graph;\n}\n\nexport function b2DestroyGraph(graph)\n{\n for (let i = 0; i < b2_graphColorCount; i++)\n {\n const color = graph.colors[i];\n\n // console.assert( i != b2_overflowIndex || color.bodySet.bits == null );\n b2DestroyBitSet(color.bodySet); color.bodySet = null;\n color.contacts = null;\n color.joints = null;\n }\n}\n\nexport function b2AddContactToGraph(world, contactSim, contact)\n{\n if (contactSim.manifold.pointCount <= 0)\n {\n throw new Error(\"Assert failed: contactSim.manifold.pointCount > 0\");\n }\n\n if (!(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag))\n {\n throw new Error(\"Assert failed: contactSim.simFlags & b2_simTouchingFlag\");\n }\n\n if (!(contact.flags & b2ContactFlags.b2_contactTouchingFlag))\n {\n throw new Error(\"Assert failed: contact.flags & b2_contactTouchingFlag\");\n }\n\n const graph = world.constraintGraph;\n const colorIndex = b2_overflowIndex;\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex == b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex == b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const color = graph.colors[colorIndex];\n contact.colorIndex = colorIndex;\n contact.localIndex = color.contacts.count;\n\n const newContact = b2AddContact(color.contacts); // add a b2ContactSim to the color.contacts array and return it\n newContact.set(contactSim);\n\n if (staticA)\n {\n newContact.bodySimIndexA = B2_NULL_INDEX;\n newContact.invMassA = 0.0;\n newContact.invIA = 0.0;\n }\n else\n {\n if (bodyA.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyA.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexA = localIndex;\n\n const bodySimA = awakeSet.sims.data[localIndex];\n newContact.invMassA = bodySimA.invMass;\n newContact.invIA = bodySimA.invInertia;\n }\n\n if (staticB)\n {\n newContact.bodySimIndexB = B2_NULL_INDEX;\n newContact.invMassB = 0.0;\n newContact.invIB = 0.0;\n }\n else\n {\n if (bodyB.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: bodyB.setIndex == b2SetType.b2_awakeSet\");\n }\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const localIndex = bodyB.localIndex;\n\n if (!(0 <= localIndex && localIndex < awakeSet.sims.count))\n {\n throw new Error(\"Assert failed: 0 <= localIndex && localIndex < awakeSet.sims.count\");\n }\n newContact.bodySimIndexB = localIndex;\n\n const bodySimB = awakeSet.sims.data[localIndex];\n newContact.invMassB = bodySimB.invMass;\n newContact.invIB = bodySimB.invInertia;\n }\n}\n\nexport function b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n if (colorIndex !== b2_overflowIndex)\n {\n throw new Error(\"Assert failed: colorIndex == b2_overflowIndex\");\n }\n const color = graph.colors[colorIndex];\n\n if ( colorIndex != b2_overflowIndex )\n {\n // might clear a bit for a static body, but this has no effect\n b2ClearBit( color.bodySet, bodyIdA );\n b2ClearBit( color.bodySet, bodyIdB );\n }\n\n const movedIndex = b2RemoveContact(color.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix index on swapped contact\n const movedContactSim = color.contacts.data[localIndex];\n\n // Fix moved contact\n const movedId = movedContactSim.contactId;\n const movedContact = world.contactArray[movedId];\n\n if (movedContact.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedContact.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedContact.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedContact.colorIndex == colorIndex\");\n }\n\n if (movedContact.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedContact.localIndex == movedIndex\");\n }\n movedContact.localIndex = localIndex;\n }\n}\n\nfunction b2AssignJointColor(graph, bodyIdA, bodyIdB, staticA, staticB)\n{\n console.assert( staticA == false || staticB == false );\n\n return b2_overflowIndex;\n}\n\nexport function b2CreateJointInGraph(world, joint)\n{\n const graph = world.constraintGraph;\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n\n // array_h.b2CheckIndex(world.bodyArray, bodyIdA);\n // array_h.b2CheckIndex(world.bodyArray, bodyIdB);\n\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n const staticA = bodyA.setIndex === b2SetType.b2_staticSet;\n const staticB = bodyB.setIndex === b2SetType.b2_staticSet;\n\n if (staticA && staticB)\n {\n throw new Error(\"Assert failed: staticA == false || staticB == false\");\n }\n\n const colorIndex = b2AssignJointColor( graph, bodyIdA, bodyIdB, staticA, staticB );\n\n const jointSim = b2AddJoint(graph.colors[colorIndex].joints);\n joint.colorIndex = colorIndex;\n joint.localIndex = graph.colors[colorIndex].joints.count - 1;\n\n return jointSim;\n}\n\nexport function b2AddJointToGraph(world, jointSim, joint)\n{\n const jointDst = b2CreateJointInGraph(world, joint);\n Object.assign(jointDst, jointSim);\n}\n\nexport function b2RemoveJointFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex)\n{\n const graph = world.constraintGraph;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graph.colors[colorIndex];\n\n if (colorIndex != b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, bodyIdA);\n b2ClearBit(color.bodySet, bodyIdB);\n }\n\n // remove joint localIndex\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // array_h.b2CheckIndex(world.jointArray, movedId);\n if (movedId != world.jointArray[movedId].jointId)\n {\n throw new Error(\"Assert failed: movedId != jointId\");\n }\n\n const movedJoint = world.jointArray[movedId];\n\n if (movedJoint.setIndex !== b2SetType.b2_awakeSet)\n {\n throw new Error(\"Assert failed: movedJoint.setIndex == b2SetType.b2_awakeSet\");\n }\n\n if (movedJoint.colorIndex !== colorIndex)\n {\n throw new Error(\"Assert failed: movedJoint.colorIndex == colorIndex\");\n }\n\n if (movedJoint.localIndex !== movedIndex)\n {\n throw new Error(\"Assert failed: movedJoint.localIndex == movedIndex\");\n }\n\n movedJoint.localIndex = localIndex;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2Softness } from './include/solver_h.js';\nimport { b2_overflowIndex } from './include/constraint_graph_h.js';\n\n/**\n * @namespace ContactSolver\n */\n\nexport class b2ContactConstraint\n{\n constructor()\n {\n this.indexA = 0;\n this.indexB = 0;\n this.normalX = 0;\n this.normalY = 0;\n this.friction = 0;\n this.restitution = 0;\n this.pointCount = 0;\n this.softness = new b2Softness();\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.points = [];\n }\n}\n\nexport class b2ContactConstraintPoint\n{\n constructor()\n {\n this.normalImpulse = 0;\n this.tangentImpulse = 0;\n this.maxNormalImpulse = 0;\n this.anchorAX = 0;\n this.anchorAY = 0;\n this.anchorBX = 0;\n this.anchorBY = 0;\n this.baseSeparation = 0;\n this.normalMass = 0;\n this.tangentMass = 0;\n this.relativeVelocity = 0;\n }\n}\n\nexport function b2PrepareOverflowContacts(context)\n{\n const world = context.world;\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const contacts = color.contacts.data;\n const awakeStates = context.states;\n\n // const bodies = world.bodyArray; // debug only\n \n const contactSoftness = context.contactSoftness;\n const staticSoftness = context.staticSoftness;\n\n const warmStartScale = world.enableWarmStarting ? 1.0 : 0.0;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = contacts[i];\n const manifold = contactSim.manifold;\n const pointCount = manifold.pointCount;\n\n const indexA = contactSim.bodySimIndexA;\n const indexB = contactSim.bodySimIndexB;\n\n // #if B2_VALIDATE debug only\n // const bodyA = bodies[contactSim._bodyIdA];\n // const validIndexA = bodyA.setIndex == b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n // console.assert( indexA == validIndexA );\n\n // const bodyB = bodies[contactSim._bodyIdB];\n // const validIndexB = bodyB.setIndex == b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n // console.assert( indexB == validIndexB );\n // #endif\n\n const constraint = constraints[i];\n constraint.indexA = indexA;\n constraint.indexB = indexB;\n constraint.normalX = manifold.normalX;\n constraint.normalY = manifold.normalY;\n constraint.friction = contactSim.friction;\n constraint.restitution = contactSim.restitution;\n constraint.pointCount = pointCount;\n\n // let vA = new b2Vec2();\n let vAX = 0;\n let vAY = 0;\n let wA = 0;\n const mA = contactSim.invMassA;\n const iA = contactSim.invIA;\n\n if (indexA !== B2_NULL_INDEX)\n {\n const stateA = awakeStates[indexA];\n vAX = stateA.linearVelocity.x;\n vAY = stateA.linearVelocity.y;\n wA = stateA.angularVelocity;\n }\n\n // let vB = new b2Vec2();\n let vBX = 0;\n let vBY = 0;\n let wB = 0;\n const mB = contactSim.invMassB;\n const iB = contactSim.invIB;\n\n if (indexB !== B2_NULL_INDEX)\n {\n const stateB = awakeStates[indexB];\n vBX = stateB.linearVelocity.x;\n vBY = stateB.linearVelocity.y;\n wB = stateB.angularVelocity;\n }\n\n constraint.softness = (indexA === B2_NULL_INDEX || indexB === B2_NULL_INDEX) ? staticSoftness : contactSoftness;\n\n constraint.invMassA = mA;\n constraint.invIA = iA;\n constraint.invMassB = mB;\n constraint.invIB = iB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentX = constraint.normalY;\n const tangentY = -constraint.normalX;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const mp = manifold.points[j];\n const cp = constraint.points[j] = new b2ContactConstraintPoint();\n\n cp.normalImpulse = warmStartScale * mp.normalImpulse;\n cp.tangentImpulse = warmStartScale * mp.tangentImpulse;\n cp.maxNormalImpulse = 0.0;\n\n // const rA = new b2Vec2(mp.anchorAX, mp.anchorAY);\n const rAX = mp.anchorAX;\n const rAY = mp.anchorAY;\n\n // const rB = new b2Vec2(mp.anchorBX, mp.anchorBY);\n const rBX = mp.anchorBX;\n const rBY = mp.anchorBY;\n\n // cp.anchorA = rA;\n cp.anchorAX = rAX;\n cp.anchorAY = rAY;\n\n // cp.anchorB = rB;\n cp.anchorBX = rBX;\n cp.anchorBY = rBY;\n const subX = rBX - rAX;\n const subY = rBY - rAY;\n\n // cp.baseSeparation = mp.separation - b2Dot(b2Sub(rB, rA), normal);\n cp.baseSeparation = mp.separation - (subX * normalX + subY * normalY);\n\n // const rnA = b2Cross(rA, normal);\n const rnA = rAX * normalY - rAY * normalX;\n\n // const rnB = b2Cross(rB, normal);\n const rnB = rBX * normalY - rBY * normalX;\n const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;\n cp.normalMass = kNormal > 0.0 ? 1.0 / kNormal : 0.0;\n\n // const rtA = b2Cross(rA, tangent);\n const rtA = rAX * tangentY - rAY * tangentX;\n\n // const rtB = b2Cross(rB, tangent);\n const rtB = rBX * tangentY - rBY * tangentX;\n const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;\n cp.tangentMass = kTangent > 0.0 ? 1.0 / kTangent : 0.0;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vAX + (-wA * rAY);\n const vrAY = vAY + (wA * rAX);\n\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vBX + (-wB * rBY);\n const vrBY = vBY + (wB * rBX);\n\n // cp.relativeVelocity = b2Dot(normal, b2Sub(vrB, vrA));\n cp.relativeVelocity = normalX * (vrBX - vrAX) + normalY * (vrBY - vrAY);\n }\n }\n}\n\nexport function b2WarmStartOverflowContacts(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states.data;\n\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const indexA = constraint.indexA;\n const indexB = constraint.indexB;\n\n const stateA = indexA === B2_NULL_INDEX ? dummyState : states[indexA];\n const stateB = indexB === B2_NULL_INDEX ? dummyState : states[indexB];\n\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n\n // const tangent = b2RightPerp(constraint.normal);\n const tangentx = constraint.normalY;\n const tangenty = -constraint.normalX;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // const P = b2Add(b2MulSV(cp.normalImpulse, normal), b2MulSV(cp.tangentImpulse, tangent));\n const Px = (cp.normalImpulse * normalX) + (cp.tangentImpulse * tangentx);\n const Py = (cp.normalImpulse * normalY) + (cp.tangentImpulse * tangenty);\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * Py - rAY * Px);\n\n // vA = b2MulAdd(vA, -mA, P);\n vA.x -= mA * Px;\n vA.y -= mA * Py;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * Py - rBY * Px);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * Px;\n vB.y += mB * Py;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2SolveOverflowContacts(context, useBias)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const inv_h = context.inv_h;\n const pushout = context.world.contactPushoutVelocity;\n\n // Dummy body to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n\n const constraint = constraints[i];\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n let vAX = stateA.linearVelocity.x;\n let vAY = stateA.linearVelocity.y;\n let wA = stateA.angularVelocity;\n const dqA = stateA.deltaRotation;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n let vBX = stateB.linearVelocity.x;\n let vBY = stateB.linearVelocity.y;\n let wB = stateB.angularVelocity;\n const dqB = stateB.deltaRotation;\n\n const dpx = stateB.deltaPosition.x - stateA.deltaPosition.x;\n const dpy = stateB.deltaPosition.y - stateA.deltaPosition.y;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const tangentx = normalY;\n const tangenty = -normalX;\n const friction = constraint.friction;\n const softness = constraint.softness;\n\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n // Compute current separation\n const rx = (dqB.c * cp.anchorBX - dqB.s * cp.anchorBY) - (dqA.c * cp.anchorAX - dqA.s * cp.anchorAY);\n const ry = (dqB.s * cp.anchorBX + dqB.c * cp.anchorBY) - (dqA.s * cp.anchorAX + dqA.c * cp.anchorAY);\n const s = (dpx + rx) * normalX + (dpy + ry) * normalY + cp.baseSeparation;\n\n let velocityBias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (s > 0.0)\n {\n velocityBias = s * inv_h;\n }\n else if (useBias)\n {\n velocityBias = Math.max(softness.biasRate * s, -pushout);\n massScale = softness.massScale;\n impulseScale = softness.impulseScale;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n const vn = (vBX - vAX + wB * -rBY - wA * -rAY) * normalX +\n (vBY - vAY + wB * rBX - wA * rAX) * normalY;\n\n // Incremental normal impulse\n let impulse = -cp.normalMass * massScale * (vn + velocityBias) - impulseScale * cp.normalImpulse;\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply normal impulse\n const Px = impulse * normalX;\n const Py = impulse * normalY;\n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n \n // Relative tangent velocity at contact\n const vtx = (vBX - wB * rBY) - (vAX - wA * rAY);\n const vty = (vBY + wB * rBX) - (vAY + wA * rAX);\n const vt = vtx * tangentx + vty * tangenty;\n \n // Incremental tangent impulse\n let impulse = cp.tangentMass * (-vt);\n \n // Clamp the accumulated force\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = oldTangentImpulse + impulse;\n cp.tangentImpulse = cp.tangentImpulse < -maxFriction ? -maxFriction :\n (cp.tangentImpulse > maxFriction ? maxFriction : cp.tangentImpulse);\n impulse = cp.tangentImpulse - oldTangentImpulse;\n \n // Apply tangent impulse\n const Px = impulse * tangentx;\n const Py = impulse * tangenty;\n \n vAX -= mA * Px;\n vAY -= mA * Py;\n wA -= iA * (rAX * Py - rAY * Px);\n \n vBX += mB * Px;\n vBY += mB * Py;\n wB += iB * (rBX * Py - rBY * Px);\n }\n\n stateA.linearVelocity.x = vAX;\n stateA.linearVelocity.y = vAY;\n stateA.angularVelocity = wA;\n stateB.linearVelocity.x = vBX;\n stateB.linearVelocity.y = vBY;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2ApplyOverflowRestitution(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contactCount = color.contacts.count;\n const awakeSet = context.world.solverSetArray[b2SetType.b2_awakeSet];\n const states = awakeSet.states;\n\n const threshold = context.world.restitutionThreshold;\n\n // Dummy state to represent a static body\n const dummyState = new b2BodyState();\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n\n const restitution = constraint.restitution;\n\n if (restitution === 0.0)\n {\n continue;\n }\n\n const mA = constraint.invMassA;\n const iA = constraint.invIA;\n const mB = constraint.invMassB;\n const iB = constraint.invIB;\n\n const stateA = constraint.indexA === B2_NULL_INDEX ? dummyState : states.data[constraint.indexA];\n const vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n\n const stateB = constraint.indexB === B2_NULL_INDEX ? dummyState : states.data[constraint.indexB];\n const vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const normalX = constraint.normalX;\n const normalY = constraint.normalY;\n const pointCount = constraint.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n const cp = constraint.points[j];\n\n if (cp.relativeVelocity > -threshold || cp.maxNormalImpulse === 0.0)\n {\n continue;\n }\n\n // Fixed anchor points\n const rAX = cp.anchorAX;\n const rAY = cp.anchorAY;\n const rBX = cp.anchorBX;\n const rBY = cp.anchorBY;\n\n // Relative normal velocity at contact\n // const vrB = b2Add(vB, b2CrossSV(wB, rB));\n const vrBX = vB.x + -wB * rBY;\n const vrBY = vB.y + wB * rBX;\n\n // const vrA = b2Add(vA, b2CrossSV(wA, rA));\n const vrAX = vA.x + -wA * rAY;\n const vrAY = vA.y + wA * rAX;\n\n // const vn = b2Dot(b2Sub(vrB, vrA), normal);\n const subX = vrBX - vrAX;\n const subY = vrBY - vrAY;\n const vn = subX * normalX + subY * normalY;\n\n // Compute normal impulse\n let impulse = -cp.normalMass * (vn + restitution * cp.relativeVelocity);\n\n // Clamp the accumulated impulse\n const newImpulse = Math.max(cp.normalImpulse + impulse, 0.0);\n impulse = newImpulse - cp.normalImpulse;\n cp.normalImpulse = newImpulse;\n cp.maxNormalImpulse = Math.max(cp.maxNormalImpulse, impulse);\n\n // Apply contact impulse\n // const P = b2MulSV(impulse, normal);\n const PX = impulse * normalX;\n const PY = impulse * normalY;\n\n // vA = b2MulSub(vA, mA, P);\n vA.x -= mA * PX;\n vA.y -= mA * PY;\n\n // wA -= iA * b2Cross(rA, P);\n wA -= iA * (rAX * PY - rAY * PX);\n\n // vB = b2MulAdd(vB, mB, P);\n vB.x += mB * PX;\n vB.y += mB * PY;\n\n // wB += iB * b2Cross(rB, P);\n wB += iB * (rBX * PY - rBY * PX);\n }\n\n // stateA.linearVelocity = vA; PJB: vA, vB have been references all along...\n stateA.angularVelocity = wA;\n\n // stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n }\n}\n\nexport function b2StoreOverflowImpulses(context)\n{\n const graph = context.graph;\n const color = graph.colors[b2_overflowIndex];\n const constraints = color.overflowConstraints;\n const contacts = color.contacts;\n const contactCount = color.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const constraint = constraints[i];\n const contact = contacts.data[i];\n const manifold = contact.manifold;\n const pointCount = manifold.pointCount;\n\n for (let j = 0; j < pointCount; ++j)\n {\n manifold.points[j].normalImpulse = constraint.points[j].normalImpulse;\n manifold.points[j].tangentImpulse = constraint.points[j].tangentImpulse;\n manifold.points[j].maxNormalImpulse = constraint.points[j].maxNormalImpulse;\n manifold.points[j].normalVelocity = constraint.points[j].relativeVelocity;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\n/**\n * @namespace Aabb\n */\n\n// Get surface area of an AABB (the perimeter length)\nexport function b2Perimeter(a)\n{\n const wx = a.upperBoundX - a.lowerBoundX;\n const wy = a.upperBoundY - a.lowerBoundY;\n\n return 2.0 * (wx + wy);\n}\n\nexport function b2EnlargeAABB(a, b)\n{\n let changed = false;\n\n if (b.lowerBoundX < a.lowerBoundX)\n {\n a.lowerBoundX = b.lowerBoundX;\n changed = true;\n }\n\n if (b.lowerBoundY < a.lowerBoundY)\n {\n a.lowerBoundY = b.lowerBoundY;\n changed = true;\n }\n\n if (a.upperBoundX < b.upperBoundX)\n {\n a.upperBoundX = b.upperBoundX;\n changed = true;\n }\n\n if (a.upperBoundY < b.upperBoundY)\n {\n a.upperBoundY = b.upperBoundY;\n changed = true;\n }\n\n return changed;\n}\n\nexport function b2AABB_Overlaps(a, b)\n{\n return !(a.lowerBoundX >= b.upperBoundX ||\n a.upperBoundX <= b.lowerBoundX ||\n a.lowerBoundY >= b.upperBoundY ||\n a.upperBoundY <= b.lowerBoundY);\n}\n\n/**\n * Validates an Axis-Aligned Bounding Box (AABB)\n * @function b2AABB_IsValid\n * @param {b2AABB} aabb - The AABB to validate\n * @returns {boolean} True if the AABB exists and has valid dimensions and coordinates\n * @description\n * Checks if an AABB is valid by verifying:\n * 1. The AABB object exists\n * 2. The width (upperBoundX - lowerBoundX) is non-negative\n * 3. The height (upperBoundY - lowerBoundY) is non-negative\n * 4. All coordinate values are valid numbers\n */\nexport function b2AABB_IsValid(aabb)\n{\n const dx = aabb.upperBoundX - aabb.lowerBoundX; // b2Math.b2Sub(a.upperBound, a.lowerBound);\n const dy = aabb.upperBoundY - aabb.lowerBoundY;\n let valid = dx >= 0.0 && dy >= 0.0;\n valid = valid && b2Math.b2IsValid(aabb.lowerBoundX) && b2Math.b2IsValid(aabb.lowerBoundY)\n && b2Math.b2IsValid(aabb.upperBoundX) && b2Math.b2IsValid(aabb.upperBoundY);\n\n return valid;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as b2Math from './include/math_functions_h.js';\n\nimport { B2_HUGE, B2_NULL_INDEX } from './include/core_h.js';\nimport { b2AABB_Overlaps, b2EnlargeAABB, b2Perimeter } from './include/aabb_h.js';\n\nimport { b2DynamicTree } from './include/dynamic_tree_h.js';\nimport { b2PairQueryCallback } from './include/broad_phase_h.js';\nimport { b2TreeNode } from './include/collision_h.js';\n\n/**\n * @namespace DynamicTree\n */\n\nconst B2_TREE_STACK_SIZE = 1024;\n\nfunction b2IsLeaf(node)\n{\n return node.height === 0;\n}\n\n/**\n * Creates and initializes a new b2DynamicTree instance.\n * @function b2DynamicTree_Create\n * @returns {b2DynamicTree} A new dynamic tree with:\n * - Initial node capacity of 16\n * - Empty root (B2_NULL_INDEX)\n * - Initialized node array with parent/next pointers\n * - All nodes set to height -1\n * - Free list starting at index 0\n * - Zero proxy count\n * - Null leaf indices and centers\n * - Zero rebuild capacity\n * @description\n * Creates a b2DynamicTree data structure used for efficient spatial partitioning.\n * The tree is initialized with a pre-allocated pool of nodes linked in a free list.\n */\nexport function b2DynamicTree_Create()\n{\n\n const tree = new b2DynamicTree();\n tree.root = B2_NULL_INDEX;\n\n tree.nodeCapacity = 16;\n tree.nodeCount = 0;\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n\n for (let i = 0; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = 0;\n\n tree.proxyCount = 0;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n tree.rebuildCapacity = 0;\n\n return tree;\n}\n\n/**\n * @summary Destroys a dynamic tree by clearing its internal data structures.\n * @function b2DynamicTree_Destroy\n * @param {b2DynamicTree} tree - The dynamic tree to destroy.\n * @returns {void}\n * @description\n * Clears the nodes, leaf indices, and leaf centers arrays of the dynamic tree,\n * effectively destroying the tree's data structure.\n */\nexport function b2DynamicTree_Destroy(tree)\n{\n // In JavaScript, we don't need to manually free memory\n tree.nodes = null;\n tree.leafIndices = null;\n\n // tree.leafBoxes = null;\n tree.leafCenters = null;\n\n // tree.binIndices = null;\n}\n\nfunction b2AllocateNode(tree)\n{\n if (tree.freeList === B2_NULL_INDEX)\n {\n const oldNodes = tree.nodes;\n tree.nodeCapacity += tree.nodeCapacity >> 1;\n\n tree.nodes = Array.from({ length: tree.nodeCapacity }, () => new b2TreeNode()); // Array(tree.nodeCapacity).fill().map(() => new b2TreeNode());\n // tree.nodes = new Array(tree.nodeCapacity).fill().map((_, i) => {\n // if (i < oldNodes.length) {\n // return oldNodes[i];\n // } else {\n // return new b2TreeNode();\n // }\n // });\n tree.nodes = Array.from({ length: tree.nodeCapacity }, (_, i) =>\n {\n if (i < oldNodes.length)\n {\n return oldNodes[i];\n }\n else\n {\n return new b2TreeNode();\n }\n });\n \n for (let i = tree.nodeCount; i < tree.nodeCapacity - 1; ++i)\n {\n tree.nodes[i].parent_next = i + 1;\n tree.nodes[i].height = -1;\n }\n\n tree.nodes[tree.nodeCapacity - 1].parent_next = B2_NULL_INDEX;\n tree.nodes[tree.nodeCapacity - 1].height = -1;\n tree.freeList = tree.nodeCount;\n }\n\n const nodeIndex = tree.freeList;\n const node = tree.nodes[nodeIndex];\n tree.freeList = node.parent_next;\n tree.nodes[nodeIndex] = new b2TreeNode();\n ++tree.nodeCount;\n\n return nodeIndex;\n}\n\nfunction b2FreeNode(tree, nodeId)\n{\n tree.nodes[nodeId].parent_next = tree.freeList;\n tree.nodes[nodeId].height = -1;\n tree.freeList = nodeId;\n --tree.nodeCount;\n}\n\nfunction b2FindBestSibling(tree, boxD)\n{\n const centerD = b2Math.b2AABB_Center(boxD);\n const areaD = b2Perimeter(boxD);\n\n const nodes = tree.nodes;\n const rootIndex = tree.root;\n\n const rootBox = nodes[rootIndex].aabb;\n\n let areaBase = b2Perimeter(rootBox);\n\n let directCost = b2Perimeter(b2Math.b2AABB_Union(rootBox, boxD));\n let inheritedCost = 0;\n\n let bestSibling = rootIndex;\n let bestCost = directCost;\n\n let index = rootIndex;\n\n while (nodes[index].height > 0)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n\n const cost = directCost + inheritedCost;\n\n if (cost < bestCost)\n {\n bestSibling = index;\n bestCost = cost;\n }\n\n inheritedCost += directCost - areaBase;\n\n const leaf1 = nodes[child1].height === 0;\n const leaf2 = nodes[child2].height === 0;\n\n let lowerCost1 = Number.MAX_VALUE;\n const box1 = nodes[child1].aabb;\n const directCost1 = b2Perimeter(b2Math.b2AABB_Union(box1, boxD));\n let area1 = 0;\n\n if (leaf1)\n {\n const cost1 = directCost1 + inheritedCost;\n\n if (cost1 < bestCost)\n {\n bestSibling = child1;\n bestCost = cost1;\n }\n }\n else\n {\n area1 = b2Perimeter(box1);\n lowerCost1 = inheritedCost + directCost1 + Math.min(areaD - area1, 0);\n }\n\n let lowerCost2 = Number.MAX_VALUE;\n const box2 = nodes[child2].aabb;\n const directCost2 = b2Perimeter(b2Math.b2AABB_Union(box2, boxD));\n let area2 = 0;\n\n if (leaf2)\n {\n const cost2 = directCost2 + inheritedCost;\n\n if (cost2 < bestCost)\n {\n bestSibling = child2;\n bestCost = cost2;\n }\n }\n else\n {\n area2 = b2Perimeter(box2);\n lowerCost2 = inheritedCost + directCost2 + Math.min(areaD - area2, 0);\n }\n\n if (leaf1 && leaf2)\n {\n break;\n }\n\n if (bestCost <= lowerCost1 && bestCost <= lowerCost2)\n {\n break;\n }\n\n if (lowerCost1 === lowerCost2 && !leaf1)\n {\n const d1 = b2Math.b2Sub(b2Math.b2AABB_Center(box1), centerD);\n const d2 = b2Math.b2Sub(b2Math.b2AABB_Center(box2), centerD);\n lowerCost1 = b2Math.b2LengthSquared(d1);\n lowerCost2 = b2Math.b2LengthSquared(d2);\n }\n\n if (lowerCost1 < lowerCost2 && !leaf1)\n {\n index = child1;\n areaBase = area1;\n directCost = directCost1;\n }\n else\n {\n index = child2;\n areaBase = area2;\n directCost = directCost2;\n }\n }\n\n return bestSibling;\n}\n\nconst b2RotateType = {\n b2_rotateNone: 0,\n b2_rotateBF: 1,\n b2_rotateBG: 2,\n b2_rotateCD: 3,\n b2_rotateCE: 4\n};\n\n// Perform a left or right rotation if node A is imbalanced.\n// Returns the new root index.\nexport function b2RotateNodes(tree, iA)\n{\n console.assert(iA != B2_NULL_INDEX);\n\n const nodes = tree.nodes;\n\n const A = nodes[iA];\n\n if (A.height < 2)\n {\n return;\n }\n\n const iB = A.child1;\n const iC = A.child2;\n console.assert(0 <= iB && iB < tree.nodeCapacity);\n console.assert(0 <= iC && iC < tree.nodeCapacity);\n\n const B = nodes[iB];\n const C = nodes[iC];\n\n if (B.height === 0)\n {\n // B is a leaf and C is internal\n console.assert(C.height > 0);\n\n const iF = C.child1;\n const iG = C.child2;\n const F = nodes[iF];\n const G = nodes[iG];\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(C.aabb);\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = b2Perimeter(aabbBG);\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = b2Perimeter(aabbBF);\n\n if (costBase < costBF && costBase < costBG)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costBF < costBG)\n {\n // Swap B and F\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n }\n else\n {\n // Swap B and G\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n }\n }\n else if (C.height === 0)\n {\n // C is a leaf and B is internal\n console.assert(B.height > 0);\n\n const iD = B.child1;\n const iE = B.child2;\n const D = nodes[iD];\n const E = nodes[iE];\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n\n // Base cost\n const costBase = b2Perimeter(B.aabb);\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = b2Perimeter(aabbCE);\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = b2Perimeter(aabbCD);\n\n if (costBase < costCD && costBase < costCE)\n {\n // Rotation does not improve cost\n return;\n }\n\n if (costCD < costCE)\n {\n // Swap C and D\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n }\n else\n {\n // Swap C and E\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n }\n }\n else\n {\n const iD = B.child1;\n const iE = B.child2;\n const iF = C.child1;\n const iG = C.child2;\n\n const D = nodes[iD];\n const E = nodes[iE];\n const F = nodes[iF];\n const G = nodes[iG];\n\n console.assert(0 <= iD && iD < tree.nodeCapacity);\n console.assert(0 <= iE && iE < tree.nodeCapacity);\n console.assert(0 <= iF && iF < tree.nodeCapacity);\n console.assert(0 <= iG && iG < tree.nodeCapacity);\n\n // Base cost\n const areaB = b2Perimeter(B.aabb);\n const areaC = b2Perimeter(C.aabb);\n const costBase = areaB + areaC;\n let bestRotation = b2RotateType.b2_rotateNone;\n let bestCost = costBase;\n\n // Cost of swapping B and F\n const aabbBG = b2Math.b2AABB_Union(B.aabb, G.aabb);\n const costBF = areaB + b2Perimeter(aabbBG);\n\n if (costBF < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBF;\n bestCost = costBF;\n }\n\n // Cost of swapping B and G\n const aabbBF = b2Math.b2AABB_Union(B.aabb, F.aabb);\n const costBG = areaB + b2Perimeter(aabbBF);\n\n if (costBG < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateBG;\n bestCost = costBG;\n }\n\n // Cost of swapping C and D\n const aabbCE = b2Math.b2AABB_Union(C.aabb, E.aabb);\n const costCD = areaC + b2Perimeter(aabbCE);\n\n if (costCD < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCD;\n bestCost = costCD;\n }\n\n // Cost of swapping C and E\n const aabbCD = b2Math.b2AABB_Union(C.aabb, D.aabb);\n const costCE = areaC + b2Perimeter(aabbCD);\n\n if (costCE < bestCost)\n {\n bestRotation = b2RotateType.b2_rotateCE;\n\n // bestCost = costCE;\n }\n\n switch (bestRotation)\n {\n case b2RotateType.b2_rotateNone:\n break;\n\n case b2RotateType.b2_rotateBF:\n A.child1 = iF;\n C.child1 = iB;\n\n B.parent_next = iC;\n F.parent_next = iA;\n\n C.aabb = aabbBG;\n C.height = 1 + Math.max(B.height, G.height);\n A.height = 1 + Math.max(C.height, F.height);\n C.categoryBits = B.categoryBits | G.categoryBits;\n A.categoryBits = C.categoryBits | F.categoryBits;\n C.enlarged = B.enlarged || G.enlarged;\n A.enlarged = C.enlarged || F.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateBG:\n A.child1 = iG;\n C.child2 = iB;\n\n B.parent_next = iC;\n G.parent_next = iA;\n\n C.aabb = aabbBF;\n C.height = 1 + Math.max(B.height, F.height);\n A.height = 1 + Math.max(C.height, G.height);\n C.categoryBits = B.categoryBits | F.categoryBits;\n A.categoryBits = C.categoryBits | G.categoryBits;\n C.enlarged = B.enlarged || F.enlarged;\n A.enlarged = C.enlarged || G.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCD:\n A.child2 = iD;\n B.child1 = iC;\n\n C.parent_next = iB;\n D.parent_next = iA;\n\n B.aabb = aabbCE;\n B.height = 1 + Math.max(C.height, E.height);\n A.height = 1 + Math.max(B.height, D.height);\n B.categoryBits = C.categoryBits | E.categoryBits;\n A.categoryBits = B.categoryBits | D.categoryBits;\n B.enlarged = C.enlarged || E.enlarged;\n A.enlarged = B.enlarged || D.enlarged;\n\n break;\n\n case b2RotateType.b2_rotateCE:\n A.child2 = iE;\n B.child2 = iC;\n\n C.parent_next = iB;\n E.parent_next = iA;\n\n B.aabb = aabbCD;\n B.height = 1 + Math.max(C.height, D.height);\n A.height = 1 + Math.max(B.height, E.height);\n B.categoryBits = C.categoryBits | D.categoryBits;\n A.categoryBits = B.categoryBits | E.categoryBits;\n B.enlarged = C.enlarged || D.enlarged;\n A.enlarged = B.enlarged || E.enlarged;\n\n break;\n\n default:\n console.assert(false);\n\n break;\n }\n }\n}\n\nexport function b2InsertLeaf(tree, leaf, shouldRotate)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n tree.root = leaf;\n tree.nodes[tree.root].parent_next = B2_NULL_INDEX;\n\n return;\n }\n\n // Stage 1: find the best sibling for this node\n const leafAABB = tree.nodes[leaf].aabb;\n const sibling = b2FindBestSibling(tree, leafAABB);\n\n // Stage 2: create a new parent for the leaf and sibling\n const oldParent = tree.nodes[sibling].parent_next;\n const newParent = b2AllocateNode(tree);\n\n // warning: node pointer can change after allocation\n const nodes = tree.nodes;\n nodes[newParent].parent_next = oldParent;\n nodes[newParent].userData = -1;\n nodes[newParent].aabb = b2Math.b2AABB_Union(leafAABB, nodes[sibling].aabb);\n nodes[newParent].categoryBits = nodes[leaf].categoryBits | nodes[sibling].categoryBits;\n nodes[newParent].height = nodes[sibling].height + 1;\n\n if (oldParent !== B2_NULL_INDEX)\n {\n // The sibling was not the root.\n if (nodes[oldParent].child1 === sibling)\n {\n nodes[oldParent].child1 = newParent;\n }\n else\n {\n nodes[oldParent].child2 = newParent;\n }\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n }\n else\n {\n // The sibling was the root.\n nodes[newParent].child1 = sibling;\n nodes[newParent].child2 = leaf;\n nodes[sibling].parent_next = newParent;\n nodes[leaf].parent_next = newParent;\n tree.root = newParent;\n }\n\n // Stage 3: walk back up the tree fixing heights and AABBs\n let index = nodes[leaf].parent_next;\n\n while (index !== B2_NULL_INDEX)\n {\n const child1 = nodes[index].child1;\n const child2 = nodes[index].child2;\n console.assert(child1 !== B2_NULL_INDEX);\n console.assert(child2 !== B2_NULL_INDEX);\n nodes[index].aabb = b2Math.b2AABB_Union(nodes[child1].aabb, nodes[child2].aabb);\n nodes[index].categoryBits = nodes[child1].categoryBits | nodes[child2].categoryBits;\n nodes[index].height = 1 + Math.max(nodes[child1].height, nodes[child2].height);\n nodes[index].enlarged = nodes[child1].enlarged || nodes[child2].enlarged;\n\n if (shouldRotate)\n {\n b2RotateNodes(tree, index);\n }\n index = nodes[index].parent_next;\n }\n}\n\nexport function b2RemoveLeaf(tree, leaf)\n{\n if (leaf === tree.root)\n {\n tree.root = B2_NULL_INDEX;\n\n return;\n }\n\n const nodes = tree.nodes;\n const parent = nodes[leaf].parent_next;\n const grandParent = nodes[parent].parent_next;\n let sibling;\n\n if (nodes[parent].child1 === leaf)\n {\n sibling = nodes[parent].child2;\n }\n else\n {\n sibling = nodes[parent].child1;\n }\n\n if (grandParent !== B2_NULL_INDEX)\n {\n // Destroy parent and connect sibling to grandParent.\n if (nodes[grandParent].child1 === parent)\n {\n nodes[grandParent].child1 = sibling;\n }\n else\n {\n nodes[grandParent].child2 = sibling;\n }\n nodes[sibling].parent_next = grandParent;\n b2FreeNode(tree, parent);\n\n // Adjust ancestor bounds.\n let index = grandParent;\n\n while (index !== B2_NULL_INDEX)\n {\n const node = nodes[index];\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n node.height = 1 + Math.max(child1.height, child2.height);\n index = node.parent_next;\n }\n }\n else\n {\n tree.root = sibling;\n tree.nodes[sibling].parent_next = B2_NULL_INDEX;\n b2FreeNode(tree, parent);\n }\n}\n\n/**\n * Creates a proxy in a dynamic tree for collision detection. The proxy is added as a leaf node.\n * @function b2DynamicTree_CreateProxy\n * @param {b2DynamicTree} tree - The dynamic tree to add the proxy to\n * @param {b2AABB} aabb - The axis-aligned bounding box for the proxy\n * @param {number} categoryBits - The collision category bits for filtering\n * @param {number} userData - User data associated with this proxy\n * @returns {number} The ID of the created proxy node\n * @throws {Error} Throws assertion error if AABB bounds are outside valid range\n */\nexport function b2DynamicTree_CreateProxy(tree, aabb, categoryBits, userData)\n{\n console.assert( -B2_HUGE< aabb.lowerBoundX && aabb.lowerBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.lowerBoundY && aabb.lowerBoundY < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundX && aabb.upperBoundX < B2_HUGE);\n console.assert( -B2_HUGE< aabb.upperBoundY && aabb.upperBoundY < B2_HUGE);\n\n const proxyId = b2AllocateNode(tree);\n const node = tree.nodes[proxyId];\n\n node.aabb = aabb;\n node.userData = userData;\n node.categoryBits = categoryBits;\n node.height = 0;\n\n const shouldRotate = true;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n\n tree.proxyCount += 1;\n\n return proxyId;\n}\n\n/**\n * @function b2DynamicTree_DestroyProxy\n * @summary Removes and frees a proxy from the dynamic tree.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to destroy (must be >= 0 and < nodeCapacity)\n * @returns {void}\n * @throws {Error} Throws an assertion error if:\n * - proxyId is out of bounds\n * - the node is not a leaf\n * - the tree has no proxies\n * @description\n * Removes a leaf node from the tree, frees the node's memory, and decrements\n * the proxy count. The proxy must be a valid leaf node in the tree.\n */\nexport function b2DynamicTree_DestroyProxy(tree, proxyId)\n{\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n b2FreeNode(tree, proxyId);\n\n console.assert( tree.proxyCount > 0 );\n tree.proxyCount -= 1;\n}\n\n/**\n * @summary Gets the total number of proxies in a dynamic tree.\n * @function b2DynamicTree_GetProxyCount\n * @param {b2DynamicTree} tree - The dynamic tree to query.\n * @returns {number} The total count of proxies in the tree.\n * @description\n * Returns the number of proxies currently stored in the dynamic tree by accessing\n * the proxyCount property.\n */\nexport function b2DynamicTree_GetProxyCount(tree)\n{\n return tree.proxyCount;\n}\n\n/**\n * @function b2DynamicTree_MoveProxy\n * @description\n * Updates the position of a proxy in the dynamic tree by removing and reinserting it\n * with a new AABB.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to move (must be within tree.nodeCapacity)\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node at proxyId is not a leaf node\n */\nexport function b2DynamicTree_MoveProxy(tree, proxyId, aabb)\n{\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n b2RemoveLeaf(tree, proxyId);\n\n tree.nodes[proxyId].aabb = aabb;\n\n const shouldRotate = false;\n b2InsertLeaf(tree, proxyId, shouldRotate);\n}\n\n/**\n * @function b2DynamicTree_EnlargeProxy\n * @description\n * Updates a proxy's AABB in the dynamic tree and rebalances the tree structure by\n * enlarging parent nodes' AABBs as needed.\n * @param {b2DynamicTree} tree - The dynamic tree containing the proxy\n * @param {number} proxyId - The ID of the proxy to enlarge\n * @param {b2AABB} aabb - The new axis-aligned bounding box for the proxy\n * @returns {void}\n * @throws {Error} Throws assertion errors if:\n * - The AABB is invalid\n * - The AABB dimensions exceed B2_HUGE\n * - The proxyId is out of bounds\n * - The node is not a leaf\n * - The new AABB is contained within the old one\n */\nexport function b2DynamicTree_EnlargeProxy(tree, proxyId, aabb)\n{\n const nodes = tree.nodes;\n\n console.assert( b2Math.b2AABB_IsValid( aabb ) );\n console.assert( aabb.upperBoundX - aabb.lowerBoundX < B2_HUGE);\n console.assert( aabb.upperBoundY - aabb.lowerBoundY < B2_HUGE);\n console.assert( 0 <= proxyId && proxyId < tree.nodeCapacity );\n console.assert( b2IsLeaf( tree.nodes[proxyId] ) );\n\n // Caller must ensure this\n console.assert( b2Math.b2AABB_Contains( nodes[proxyId].aabb, aabb ) == false );\n\n nodes[proxyId].aabb = aabb;\n\n // enlarge parents until they don't need to be bigger to encompass aabb\n let parentIndex = nodes[proxyId].parent_next;\n\n while (parentIndex !== B2_NULL_INDEX)\n {\n const changed = b2EnlargeAABB(nodes[parentIndex].aabb, aabb);\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n\n if (!changed)\n {\n break;\n }\n }\n\n // mark all remaining parents 'enlarged' up to root (or previously marked)\n while (parentIndex !== B2_NULL_INDEX)\n {\n if (nodes[parentIndex].enlarged === true)\n {\n // early out because this ancestor was previously ascended and marked as enlarged\n break;\n }\n\n nodes[parentIndex].enlarged = true;\n parentIndex = nodes[parentIndex].parent_next;\n }\n}\n\n/**\n * @summary Gets the height of a dynamic tree\n * @function b2DynamicTree_GetHeight\n * @param {b2DynamicTree} tree - The dynamic tree to measure\n * @returns {number} The height of the tree. Returns 0 if the tree is empty (root is null)\n * @description\n * Returns the height of the specified dynamic tree by accessing the height property\n * of the root node. The height represents the maximum number of levels from the root\n * to any leaf node.\n */\nexport function b2DynamicTree_GetHeight(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0;\n }\n\n return tree.nodes[tree.root].height;\n}\n\n/**\n * @function b2DynamicTree_GetAreaRatio\n * @summary Calculates the ratio of total internal node perimeter to root node perimeter in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree structure to analyze\n * @returns {number} The ratio of total internal node perimeter to root perimeter. Returns 0 if the tree is empty.\n * @description\n * Computes the sum of all internal node perimeters (excluding leaves and root)\n * divided by the root node perimeter. This ratio provides a measure of the tree's\n * spatial organization.\n */\nexport function b2DynamicTree_GetAreaRatio(tree)\n{\n if (tree.root === B2_NULL_INDEX)\n {\n return 0.0;\n }\n\n const root = tree.nodes[tree.root];\n const rootArea = b2Perimeter(root.aabb);\n\n let totalArea = 0.0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height < 0 || b2IsLeaf(node) || i === tree.root)\n {\n // Free node in pool\n continue;\n }\n\n totalArea += b2Perimeter(node.aabb);\n }\n\n return totalArea / rootArea;\n}\n\n// // Compute the height of a sub-tree.\n// function b2ComputeHeight(tree, nodeId) {\n// console.assert( 0 <= nodeId && nodeId < tree.nodeCapacity );\n// const node = tree.nodes[nodeId];\n\n// if (b2IsLeaf(node)) {\n// return 0;\n// }\n\n// const height1 = b2ComputeHeight(tree, node.child1);\n// const height2 = b2ComputeHeight(tree, node.child2);\n// return 1 + Math.max(height1, height2);\n// }\n\n// export function b2DynamicTree_ComputeHeight(tree) {\n// const height = b2ComputeHeight(tree, tree.root);\n// return height;\n// }\n\n/**\n * @summary Validates the internal state of a dynamic tree\n * @function b2DynamicTree_Validate\n * @param {b2DynamicTree} tree - The dynamic tree to validate\n * @returns {void}\n * @description\n * Performs validation checks on a b2DynamicTree data structure to ensure\n * its internal state is consistent. This is typically used for debugging\n * and testing purposes.\n */\nexport function b2DynamicTree_Validate(tree)\n{\n // Implementation skipped due to conditional compilation\n}\n\n/**\n * @function b2DynamicTree_GetMaxBalance\n * @summary Calculates the maximum height difference between sibling nodes in a dynamic tree\n * @param {b2DynamicTree} tree - The dynamic tree to analyze\n * @returns {number} The maximum balance value (height difference) found between any pair of sibling nodes\n * @description\n * Iterates through all non-leaf nodes in the tree and calculates the absolute height difference\n * between their child nodes. Returns the largest height difference found.\n */\nexport function b2DynamicTree_GetMaxBalance(tree)\n{\n let maxBalance = 0;\n\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const node = tree.nodes[i];\n\n if (node.height <= 1)\n {\n continue;\n }\n\n console.assert(b2IsLeaf(node) == false);\n\n const child1 = node.child1;\n const child2 = node.child2;\n const balance = Math.abs(tree.nodes[child2].height - tree.nodes[child1].height);\n maxBalance = Math.max(maxBalance, balance);\n }\n\n return maxBalance;\n}\n\n/**\n * @function b2DynamicTree_RebuildBottomUp\n * @description\n * Rebuilds a dynamic tree from the bottom up by iteratively combining nodes with the lowest perimeter cost.\n * The function first identifies all leaf nodes, then pairs them based on minimum combined AABB perimeter,\n * creating parent nodes until a single root node remains.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {void}\n * @note The function validates the tree structure after rebuilding\n */\nexport function b2DynamicTree_RebuildBottomUp(tree)\n{\n const nodes = new Array(tree.nodeCount);\n let count = 0;\n\n // Build array of leaves. Free the rest.\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n if (tree.nodes[i].height < 0)\n {\n // free node in pool\n continue;\n }\n\n if (b2IsLeaf(tree.nodes[i]))\n {\n tree.nodes[i].parent_next = B2_NULL_INDEX;\n nodes[count] = i;\n ++count;\n }\n else\n {\n b2FreeNode(tree, i);\n }\n }\n\n while (count > 1)\n {\n let minCost = Number.MAX_VALUE;\n let iMin = -1,\n jMin = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const aabbi = tree.nodes[nodes[i]].aabb;\n\n for (let j = i + 1; j < count; ++j)\n {\n const aabbj = tree.nodes[nodes[j]].aabb;\n const b = b2Math.b2AABB_Union(aabbi, aabbj);\n const cost = b2Perimeter(b);\n\n if (cost < minCost)\n {\n iMin = i;\n jMin = j;\n minCost = cost;\n }\n }\n }\n\n const index_i = nodes[iMin];\n const index_j = nodes[jMin];\n const child1 = tree.nodes[index_i];\n const child2 = tree.nodes[index_j];\n\n const parentIndex = b2AllocateNode(tree);\n const parent = tree.nodes[parentIndex];\n parent.child1 = index_i;\n parent.child2 = index_j;\n parent.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n parent.categoryBits = child1.categoryBits | child2.categoryBits;\n parent.height = 1 + Math.max(child1.height, child2.height);\n parent.parent_next = B2_NULL_INDEX;\n\n child1.parent_next = parentIndex;\n child2.parent_next = parentIndex;\n\n nodes[jMin] = nodes[count - 1];\n nodes[iMin] = parentIndex;\n --count;\n }\n\n tree.root = nodes[0];\n\n b2DynamicTree_Validate(tree);\n}\n\n/**\n * @function b2DynamicTree_ShiftOrigin\n * @summary Shifts the coordinate system of all nodes in a dynamic tree by subtracting a new origin.\n * @param {b2DynamicTree} tree - The dynamic tree whose nodes will be shifted\n * @param {b2Vec2} newOrigin - The vector to subtract from all node boundaries\n * @returns {void}\n * @description\n * Updates the axis-aligned bounding boxes (AABBs) of all nodes in the tree by\n * subtracting the newOrigin vector from both their lower and upper bounds.\n */\nexport function b2DynamicTree_ShiftOrigin(tree, newOrigin)\n{\n // shift all AABBs\n for (let i = 0; i < tree.nodeCapacity; ++i)\n {\n const n = tree.nodes[i];\n n.aabb.lowerBoundX -= newOrigin.x;\n n.aabb.lowerBoundY -= newOrigin.y;\n n.aabb.upperBoundX -= newOrigin.x;\n n.aabb.upperBoundY -= newOrigin.y;\n }\n}\n\n/**\n * @function b2DynamicTree_GetByteCount\n * @summary Calculates the approximate memory usage of a dynamic tree in bytes.\n * @param {b2DynamicTree} tree - The dynamic tree instance to measure.\n * @returns {number} The estimated memory usage in bytes.\n * @description\n * Calculates the memory footprint by summing:\n * - Base object properties\n * - Node array storage\n * - Rebuild capacity storage\n */\nexport function b2DynamicTree_GetByteCount(tree)\n{\n const size = Object.keys(tree).length * 8 + // Rough estimate for object properties\n tree.nodeCapacity * Object.keys(tree.nodes[0]).length * 8 + // Estimate for nodes\n tree.rebuildCapacity * (4 + 16 + 8 + 4); // Estimate for rebuild data\n\n return size;\n}\n\n/**\n * @function b2DynamicTree_Query\n * @description\n * Queries a dynamic tree to find all nodes that overlap with the given AABB and match the category mask bits.\n * Uses a stack-based traversal to efficiently search the tree structure.\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2AABB} aabb - The axis-aligned bounding box to test for overlaps\n * @param {number} maskBits - Category bits used to filter nodes\n * @param {function} callback - Function called for each overlapping leaf node.\n * Return false to terminate early, true to continue.\n * @param {*} context - User context data passed to the callback function\n * @returns {void}\n */\nexport function b2DynamicTree_Query(tree, aabb, maskBits, callback, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n \n const stack = [];\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if ((node.categoryBits & maskBits) !== 0 && b2AABB_Overlaps(node.aabb, aabb))\n {\n // PJB: this is called a LOT, remove function call overhead\n if (node.height == 0) // b2IsLeaf(node))\n {\n // callback to user code with proxy id\n const proceed = callback(nodeId, node.userData, context);\n\n if (proceed === false)\n {\n return;\n }\n }\n else\n {\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n }\n}\n\nconst stack = Array(64); // 14 is the deepest I have seen\n\nexport function b2DynamicTree_QueryAll(tree, aabb, context)\n{\n if (tree.root == B2_NULL_INDEX)\n {\n return;\n }\n\n const lx = aabb.lowerBoundX,\n ux = aabb.upperBoundX;\n const ly = aabb.lowerBoundY,\n uy = aabb.upperBoundY;\n const nodes = tree.nodes;\n\n let stackCount = 0;\n stack[stackCount++] = tree.root;\n\n let nodeId, node, a;\n\n while (stackCount > 0)\n {\n nodeId = stack[--stackCount];\n node = nodes[nodeId];\n\n if (node.height == 0) // b2IsLeaf(node)\n {\n a = node.aabb; // weird JS optimisation, we gain 100ms (from 8600ms) if this is done inside each branch compared with doing it before\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n b2PairQueryCallback(nodeId, node.userData, context);\n }\n }\n else\n {\n a = node.aabb;\n\n if (a.lowerBoundX < ux &&\n a.upperBoundX > lx &&\n a.lowerBoundY < uy &&\n a.upperBoundY > ly)\n {\n // assumes both children will exist, following the pattern in (e.g.) b2FindBestSibling\n stack[stackCount++] = node.child1;\n stack[stackCount++] = node.child2;\n }\n }\n }\n}\n\n/**\n * @summary Performs a ray cast query on a dynamic tree\n * @function b2DynamicTree_RayCast\n * @param {b2DynamicTree} tree - The dynamic tree to query\n * @param {b2RayCastInput} input - Input parameters for the ray cast including:\n * - origin: b2Vec2 starting point\n * - translation: b2Vec2 ray direction and length\n * - maxFraction: number maximum ray length multiplier\n * @param {number} maskBits - Bit mask to filter nodes by category\n * @param {Function} callback - Function called for each leaf node intersection\n * - Parameters: (input: b2RayCastInput, nodeId: number, userData: any, context: any)\n * - Returns: number between 0 and 1 to continue search, 0 to terminate\n * @param {*} context - User context passed to callback\n * @description\n * Traverses the dynamic tree and finds all leaf nodes that intersect with the input ray.\n * For each intersection, calls the callback function which can control continuation of the search.\n * Uses an AABB overlap test and separating axis test to efficiently cull branches.\n */\nexport function b2DynamicTree_RayCast(tree, input, maskBits, callback, context)\n{\n const p1 = input.origin;\n const d = input.translation;\n\n const r = b2Math.b2Normalize(d);\n\n // v is perpendicular to the segment.\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n let p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n\n // Build a bounding box for the segment.\n // let segmentAABB = new b2Math.b2AABB(b2Math.b2Min(p1, p2), b2Math.b2Max(p1, p2));\n const segmentAABB = new b2Math.b2AABB(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));\n\n const stack = [];\n stack.push(tree.root);\n\n const subInput = input;\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, segmentAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2AABB_Extents(node.aabb);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value <= maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n p2 = b2Math.b2MulAdd(p1, maxFraction, d);\n segmentAABB.lowerBoundX = Math.min(p1.x, p2.x);\n segmentAABB.lowerBoundY = Math.min(p1.y, p2.y);\n segmentAABB.upperBoundX = Math.max(p1.x, p2.x);\n segmentAABB.upperBoundY = Math.max(p1.y, p2.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n/**\n * @function b2DynamicTree_ShapeCast\n * @description\n * Performs a shape cast query against nodes in a dynamic tree, testing for overlaps\n * between a moving shape and static shapes in the tree.\n * @param {b2DynamicTree} tree - The dynamic tree to query against\n * @param {b2ShapeCastInput} input - Contains the shape definition, translation vector,\n * radius, and maximum fraction for the cast\n * @param {number} maskBits - Bit mask to filter tree nodes by category\n * @param {Function} callback - Function called when potential overlaps are found.\n * Returns a fraction value to continue or terminate the cast\n * @param {*} context - User data passed to the callback function\n * @returns {void}\n * The callback function should have the signature:\n * function(input: b2ShapeCastInput, nodeId: number, userData: any, context: any): number\n * It should return 0 to terminate the cast, or a fraction between 0 and 1 to update the cast distance\n */\nexport function b2DynamicTree_ShapeCast(tree, input, maskBits, callback, context)\n{\n if (input.count == 0)\n {\n return;\n }\n\n const originAABB = new b2Math.b2AABB(input.points[0], input.points[0]);\n\n for (let i = 1; i < input.count; ++i)\n {\n originAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, input.points[i].x);\n originAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, input.points[i].y);\n originAABB.upperBoundX = Math.max(originAABB.upperBoundX, input.points[i].x);\n originAABB.upperBoundY = Math.max(originAABB.upperBoundY, input.points[i].y);\n }\n\n // let radius = new b2Math.b2Vec2(input.radius, input.radius);\n\n // originAABB.lowerBound = b2Math.b2Sub(originAABB.lowerBound, radius);\n originAABB.lowerBoundX = originAABB.lowerBoundX - input.radius;\n originAABB.lowerBoundY = originAABB.lowerBoundY - input.radius;\n originAABB.upperBoundX = originAABB.upperBoundX + input.radius;\n originAABB.upperBoundY = originAABB.upperBoundY + input.radius;\n\n const p1 = b2Math.b2AABB_Center(originAABB);\n const extension = b2Math.b2AABB_Extents(originAABB);\n\n // v is perpendicular to the segment.\n const r = input.translation;\n const v = b2Math.b2CrossSV(1.0, r);\n const abs_v = b2Math.b2Abs(v);\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n\n let maxFraction = input.maxFraction;\n\n // Build total box for the shape cast\n let t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // let totalAABB = new b2Math.b2AABB(b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t)),b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t)));\n const totalAABB = new b2Math.b2AABB(\n Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x),\n Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y),\n Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x),\n Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y)\n );\n\n const subInput = input;\n\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n stack.push(tree.root);\n\n while (stack.length > 0)\n {\n const nodeId = stack.pop();\n\n if (nodeId == B2_NULL_INDEX)\n {\n continue;\n }\n\n const node = tree.nodes[nodeId];\n\n if (b2AABB_Overlaps(node.aabb, totalAABB) == false || (node.categoryBits & maskBits) == 0)\n {\n continue;\n }\n\n // Separating axis for segment (Gino, p80).\n // |dot(v, p1 - c)| > dot(|v|, h)\n // radius extension is added to the node in this case\n const c = b2Math.b2AABB_Center(node.aabb);\n const h = b2Math.b2Add(b2Math.b2AABB_Extents(node.aabb), extension);\n const term1 = Math.abs(b2Math.b2Dot(v, b2Math.b2Sub(p1, c)));\n const term2 = b2Math.b2Dot(abs_v, h);\n\n if (term2 < term1)\n {\n continue;\n }\n\n if (node.height == 0) // b2IsLeaf(node))\n {\n subInput.maxFraction = maxFraction;\n\n const value = callback(subInput, nodeId, node.userData, context);\n\n if (value == 0.0)\n {\n // The client has terminated the ray cast.\n return;\n }\n\n if (0.0 < value && value < maxFraction)\n {\n // Update segment bounding box.\n maxFraction = value;\n t = b2Math.b2MulSV(maxFraction, input.translation);\n\n // totalAABB.lowerBound = b2Math.b2Min(originAABB.lowerBound, b2Math.b2Add(originAABB.lowerBound, t));\n // totalAABB.upperBound = b2Math.b2Max(originAABB.upperBound, b2Math.b2Add(originAABB.upperBound, t));\n totalAABB.lowerBoundX = Math.min(originAABB.lowerBoundX, originAABB.lowerBoundX + t.x);\n totalAABB.lowerBoundY = Math.min(originAABB.lowerBoundY, originAABB.lowerBoundY + t.y);\n totalAABB.upperBoundX = Math.max(originAABB.upperBoundX, originAABB.upperBoundX + t.x);\n totalAABB.upperBoundY = Math.max(originAABB.upperBoundY, originAABB.upperBoundY + t.y);\n }\n }\n else\n {\n // TODO_ERIN just put one node on the stack, continue on a child node\n // TODO_ERIN test ordering children by nearest to ray origin\n stack.push(node.child1);\n stack.push(node.child2);\n }\n }\n}\n\n// Median split heuristic\nfunction b2PartitionMid(indices, centers, startIndex, endIndex, count)\n{\n // Handle trivial case\n if (count <= 2)\n {\n return startIndex + (count >> 1);\n }\n\n // Create bounding box enclosing all centers\n let lowerBoundX = centers[startIndex].x;\n let upperBoundX = centers[startIndex].x;\n let lowerBoundY = centers[startIndex].y;\n let upperBoundY = centers[startIndex].y;\n\n for (let i = startIndex + 1; i < endIndex; ++i)\n {\n const x = centers[i].x;\n const y = centers[i].y;\n\n if (x < lowerBoundX) { lowerBoundX = x; }\n else if (x > upperBoundX) { upperBoundX = x; }\n\n if (y < lowerBoundY) { lowerBoundY = y; }\n else if (y > upperBoundY) { upperBoundY = y; }\n }\n\n // Find the longer box dimension\n const dX = upperBoundX - lowerBoundX;\n const dY = upperBoundY - lowerBoundY;\n const dirX = dX > dY;\n\n // Partition using the Hoare partition scheme\n let left = startIndex;\n let right = endIndex - 1;\n\n if (dirX)\n {\n const pivot = 0.5 * (lowerBoundX + upperBoundX);\n\n while (true)\n {\n while (left <= right && centers[left].x < pivot) { left++; }\n\n while (left <= right && centers[right].x > pivot) { right--; }\n\n if (left >= right) { break; }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n else\n {\n const pivot = 0.5 * (lowerBoundY + upperBoundY);\n\n while (true)\n {\n while (left <= right && centers[left].y < pivot)\n {\n left++;\n }\n\n while (left <= right && centers[right].y > pivot)\n {\n right--;\n }\n\n if (left >= right)\n {\n break;\n }\n\n // Swap indices and centers\n let temp = indices[left];\n indices[left] = indices[right];\n indices[right] = temp;\n\n temp = centers[left];\n centers[left] = centers[right];\n centers[right] = temp;\n\n left++;\n right--;\n }\n }\n\n return left > startIndex && left < endIndex ? left : (startIndex + (count >> 1));\n}\n\nfunction b2BuildTree(tree, leafCount)\n{\n const { nodes, leafIndices, leafCenters } = tree;\n\n if (leafCount === 1)\n {\n nodes[leafIndices[0]].parent_next = B2_NULL_INDEX;\n\n return leafIndices[0];\n }\n\n const stack = new Array(B2_TREE_STACK_SIZE);\n let top = 0;\n\n stack[0] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex: 0,\n endIndex: leafCount,\n splitIndex: b2PartitionMid(leafIndices, leafCenters, 0, leafCount, leafCount)\n };\n\n while (true)\n {\n const item = stack[top];\n item.childCount++;\n\n if (item.childCount === 2)\n {\n if (top === 0) { break; }\n\n const parentItem = stack[top - 1];\n const parentNode = nodes[parentItem.nodeIndex];\n const childIndex = item.nodeIndex;\n\n if (parentItem.childCount === 0)\n {\n parentNode.child1 = childIndex;\n }\n else\n {\n parentNode.child2 = childIndex;\n }\n\n const node = nodes[childIndex];\n node.parent_next = parentItem.nodeIndex;\n\n const child1 = nodes[node.child1];\n const child2 = nodes[node.child2];\n\n node.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n node.height = 1 + Math.max(child1.height, child2.height);\n node.categoryBits = child1.categoryBits | child2.categoryBits;\n\n top--;\n }\n else\n {\n const [ startIndex, endIndex ] = item.childCount === 0\n ? [ item.startIndex, item.splitIndex ]\n : [ item.splitIndex, item.endIndex ];\n\n const count = endIndex - startIndex;\n\n if (count === 1)\n {\n const childIndex = leafIndices[startIndex];\n const node = nodes[item.nodeIndex];\n \n node[item.childCount === 0 ? 'child1' : 'child2'] = childIndex;\n\n nodes[childIndex].parent_next = item.nodeIndex;\n }\n else\n {\n stack[++top] = {\n nodeIndex: b2AllocateNode(tree),\n childCount: -1,\n startIndex,\n endIndex,\n splitIndex: b2PartitionMid(\n leafIndices,\n leafCenters,\n startIndex, endIndex,\n count\n )\n };\n }\n }\n }\n\n const rootNode = nodes[stack[0].nodeIndex];\n const child1 = nodes[rootNode.child1];\n const child2 = nodes[rootNode.child2];\n\n rootNode.aabb = b2Math.b2AABB_Union(child1.aabb, child2.aabb);\n rootNode.height = 1 + Math.max(child1.height, child2.height);\n rootNode.categoryBits = child1.categoryBits | child2.categoryBits;\n\n return stack[0].nodeIndex;\n}\n\n/**\n * @function b2DynamicTree_Rebuild\n * @description\n * Rebuilds a dynamic tree by collecting all leaf nodes and reconstructing the tree structure.\n * The function deallocates internal nodes during traversal and builds a new balanced tree\n * from the collected leaf nodes.\n * @param {b2DynamicTree} tree - The dynamic tree to rebuild\n * @returns {number} The number of leaf nodes in the rebuilt tree\n * @note If the proxy count exceeds the rebuild capacity, the internal arrays are resized\n * to accommodate the new size plus 50% additional capacity. It is not safe to access the tree during this operation because it may grow.\n */\nexport function b2DynamicTree_Rebuild(tree)\n{\n const proxyCount = tree.proxyCount;\n\n if (proxyCount === 0)\n {\n return 0;\n }\n\n // Ensure capacity for rebuild space\n if (proxyCount > tree.rebuildCapacity)\n {\n const newCapacity = proxyCount + Math.floor(proxyCount / 2);\n\n tree.leafIndices = Array(newCapacity);\n tree.leafCenters = Array(newCapacity);\n tree.rebuildCapacity = newCapacity;\n }\n\n let leafCount = 0;\n const stack = []; // new Array(B2_TREE_STACK_SIZE);\n\n let nodeIndex = tree.root;\n const nodes = tree.nodes;\n let node = nodes[nodeIndex];\n\n // These are the nodes that get sorted to rebuild the tree.\n // I'm using indices because the node pool may grow during the build.\n const leafIndices = tree.leafIndices;\n const leafCenters = tree.leafCenters;\n\n // Gather all proxy nodes that have grown and all internal nodes that haven't grown. Both are\n // considered leaves in the tree rebuild.\n // Free all internal nodes that have grown.\n while (true)\n {\n if (node.height === 0 || node.enlarged === false)\n {\n leafIndices[leafCount] = nodeIndex;\n leafCenters[leafCount] = b2Math.b2AABB_Center(node.aabb);\n leafCount++;\n\n // Detach\n node.parent_next = B2_NULL_INDEX;\n }\n else\n {\n const doomedNodeIndex = nodeIndex;\n\n // Handle children, push child2 for later, process child1 immediately\n stack.push(node.child2);\n\n nodeIndex = node.child1;\n node = nodes[nodeIndex];\n\n // Remove doomed node\n b2FreeNode(tree, doomedNodeIndex);\n\n continue;\n }\n\n // check here instead of in while, node is carried around to the next iteration\n if (stack.length === 0)\n {\n break;\n }\n\n nodeIndex = stack.pop();\n node = nodes[nodeIndex];\n }\n\n console.assert(leafCount <= proxyCount);\n\n tree.root = b2BuildTree(tree, leafCount);\n\n return leafCount;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX } from '../core_c.js';\n\nexport {\n b2DynamicTree_Create, b2DynamicTree_Destroy, b2DynamicTree_CreateProxy, b2DynamicTree_DestroyProxy,\n b2DynamicTree_GetProxyCount, b2DynamicTree_MoveProxy, b2DynamicTree_EnlargeProxy, b2DynamicTree_GetHeight,\n b2DynamicTree_GetAreaRatio, b2DynamicTree_Validate,\n b2DynamicTree_Query, b2DynamicTree_QueryAll,\n b2DynamicTree_RayCast, b2DynamicTree_ShapeCast, b2DynamicTree_Rebuild, b2RotateNodes,\n b2InsertLeaf, b2RemoveLeaf,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from '../dynamic_tree_c.js';\n\n/**\n * Get proxy user data\n * @param {Object} tree - The dynamic tree object\n * @param {number} proxyId - The proxy ID\n * @returns {number} The proxy user data or 0 if the id is invalid\n */\nexport function b2DynamicTree_GetUserData(tree, proxyId)\n{\n const node = tree.nodes[proxyId];\n\n return node ? node.userData : 0;\n}\n\nexport function b2DynamicTree_GetAABB(tree, proxyId)\n{\n return proxyId in tree.nodes ? tree.nodes[proxyId].aabb : null;\n\n // PJB - never seems to fail, avoid the branch overhead: this is called a lot\n // return tree.nodes[proxyId].aabb;\n}\n\n/**\n * @class b2DynamicTree\n * @summary The dynamic tree structure used internally for performance reasons\n * @property {b2TreeNode[]} nodes - The tree nodes\n * @property {number} root - The root index\n * @property {number} nodeCount - The number of nodes\n * @property {number} nodeCapacity - The allocated node space\n * @property {number} freeList - Node free list\n * @property {number} proxyCount - Number of proxies created\n * @property {number[]} leafIndices - Leaf indices for rebuild\n * @property {b2AABB[]} leafBoxes - Leaf bounding boxes for rebuild\n * @property {b2Vec2[]} leafCenters - Leaf bounding box centers for rebuild\n * @property {number[]} binIndices - Bins for sorting during rebuild\n * @property {number} rebuildCapacity - Allocated space for rebuilding\n */\nexport class b2DynamicTree\n{\n constructor()\n {\n this.nodes = [];\n this.root = 0;\n this.nodeCount = 0;\n this.nodeCapacity = 0;\n this.freeList = B2_NULL_INDEX;\n this.proxyCount = 0;\n this.leafIndices = [];\n\n // this.leafBoxes = [];\n this.leafCenters = [];\n\n // this.binIndices = [];\n this.rebuildCapacity = 0;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport function b2IsPowerOf2(x)\n{\n return (x & (x - 1)) === 0;\n}\n\nexport function b2BoundingPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 32 - Math.clz32(x - 1);\n}\n\nexport function b2RoundUpPowerOf2(x)\n{\n if (x <= 1)\n {\n return 1;\n }\n\n return 1 << (32 - Math.clz32(x - 1));\n}\n\nexport function b2CTZ64(block)\n{\n // 64; PJB closer to the _BitScanForward64 implementation\n if (block === 0n)\n {\n return 0;\n }\n \n const low32 = Number(block & 0xFFFFFFFFn);\n\n if (low32 !== 0)\n {\n return Math.clz32(low32 & -low32) ^ 31;\n }\n else\n {\n const high32 = Number(block >> 32n);\n\n return Math.clz32(high32 & -high32) ^ 31 | 32;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n b2AddBodySim,\n b2AddBodyState,\n b2AddContact,\n b2AddIsland,\n b2AddJoint,\n b2BodySimArray,\n b2BodyStateArray,\n b2ContactArray,\n b2CreateBodySimArray,\n b2CreateContactArray,\n b2CreateJointArray,\n b2IslandArray,\n b2JointArray,\n b2RemoveBodySim,\n b2RemoveBodyState,\n b2RemoveContact,\n b2RemoveIsland,\n b2RemoveJoint,\n} from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2AddJointToGraph, b2RemoveJointFromGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2ContactFlags, b2ContactSimFlags } from './include/contact_h.js';\nimport { b2SetType, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2BodyState } from './include/body_h.js';\nimport { b2ClearBit } from './include/bitset_h.js';\n\n/**\n * @namespace SolverSet\n */\n\n// This holds solver set data. The following sets are used:\n// - static set for all static bodies (no contacts or joints)\n// - active set for all active bodies with body states (no contacts or joints)\n// - disabled set for disabled bodies and their joints\n// - all further sets are sleeping island sets along with their contacts and joints\n// The purpose of solver sets is to achieve high memory locality.\n// https://www.youtube.com/watch?v=nZNd5FjSquk\nexport class b2SolverSet\n{\n constructor()\n {\n // Body array. Empty for unused set.\n this.sims = new b2BodySimArray();\n\n // Body state only exists for active set\n this.states = new b2BodyStateArray();\n\n // This holds sleeping/disabled joints. Empty for static/active set.\n this.joints = new b2JointArray();\n\n // This holds all contacts for sleeping sets.\n // This holds non-touching contacts for the awake set.\n this.contacts = new b2ContactArray();\n\n // The awake set has an array of islands. Sleeping sets normally have a single islands. However, joints\n // created between sleeping sets causes the sets to merge, leaving them with multiple islands. These sleeping\n // islands will be naturally merged with the set is woken.\n // The static and disabled sets have no islands.\n // Islands live in the solver sets to limit the number of islands that need to be considered for sleeping.\n this.islands = new b2IslandArray();\n\n // Aligns with b2World::solverSetIdPool. Used to create a stable id for body/contact/joint/islands.\n this.setIndex = 0;\n \n }\n}\n\nexport function b2DestroySolverSet(world, setIndex)\n{\n console.assert(setIndex >= 0);\n let set = world.solverSetArray[setIndex];\n set.sims = null;\n set.states = null;\n set.contacts = null;\n set.joints = null;\n set.islands = null;\n b2FreeId(world.solverSetIdPool, setIndex);\n set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray[setIndex] = set;\n}\n\nexport function b2WakeSolverSet(world, setIndex)\n{\n console.assert(setIndex >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const bodyCount = set.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setIndex);\n body.setIndex = b2SetType.b2_awakeSet;\n body.localIndex = awakeSet.sims.count;\n\n body.sleepTime = 0.0;\n\n const simDst = b2AddBodySim(awakeSet.sims);\n Object.assign(simDst, simSrc);\n\n const state = b2AddBodyState(awakeSet.states);\n Object.assign(state, new b2BodyState());\n\n // move non-touching contacts from disabled set to awake set\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const edgeIndex = contactKey & 1;\n const contactId = contactKey >> 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_disabledSet)\n {\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === setIndex);\n\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < disabledSet.contacts.count);\n const contactSim = disabledSet.contacts.data[localIndex];\n\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 && contactSim.manifold.pointCount === 0);\n\n contact.setIndex = b2SetType.b2_awakeSet;\n contact.localIndex = awakeSet.contacts.count;\n const awakeContactSim = b2AddContact(awakeSet.contacts);\n awakeContactSim.set(contactSim);\n\n const movedLocalIndex = b2RemoveContact(disabledSet.contacts, localIndex);\n\n if (movedLocalIndex !== B2_NULL_INDEX)\n {\n const movedContact = disabledSet.contacts.data[localIndex];\n const movedId = movedContact.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedLocalIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n }\n\n const contactCount = set.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSim = set.contacts.data[i];\n const contact = contacts[contactSim.contactId];\n console.assert(contact.flags & b2ContactFlags.b2_contactTouchingFlag);\n console.assert(contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag);\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex === setIndex);\n b2AddContactToGraph(world, contactSim, contact);\n contact.setIndex = b2SetType.b2_awakeSet;\n }\n\n const joints = world.jointArray;\n const jointCount = set.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSim = set.joints.data[i];\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n b2AddJointToGraph(world, jointSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n\n const islands = world.islandArray;\n const islandCount = set.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set.islands.data[i];\n\n // b2CheckIndex(islands, islandSrc.islandId);\n const island = islands[islandSrc.islandId];\n island.setIndex = b2SetType.b2_awakeSet;\n island.localIndex = awakeSet.islands.count;\n const islandDst = b2AddIsland(awakeSet.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setIndex);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TrySleepIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.setIndex === b2SetType.b2_awakeSet, `b2TrySleepIsland island.setIndex is not awakeSet: ${island.setIndex}`);\n\n if (island.constraintRemoveCount > 0)\n {\n return;\n }\n\n const moveEvents = world.bodyMoveEventArray;\n\n const sleepSetId = b2AllocId(world.solverSetIdPool);\n\n if (sleepSetId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = B2_NULL_INDEX;\n world.solverSetArray.push(set);\n }\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= island.localIndex && island.localIndex < awakeSet.islands.count);\n\n const sleepSet = world.solverSetArray[sleepSetId];\n sleepSet.setIndex = sleepSetId;\n sleepSet.sims = b2CreateBodySimArray(island.bodyCount);\n sleepSet.contacts = b2CreateContactArray(island.contactCount);\n sleepSet.joints = b2CreateJointArray(island.jointCount);\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n let bodyId = island.headBody;\n\n // (\"headBody \" + island.headBody + \" tailBody \" + island.tailBody + \" bodyCount \" + island.bodyCount);\n while (bodyId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.islandId === islandId);\n\n if (body.bodyMoveIndex !== B2_NULL_INDEX)\n {\n // b2CheckIndex(moveEvents, body.bodyMoveIndex);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.index1 - 1 === bodyId);\n console.assert(moveEvents[body.bodyMoveIndex].bodyId.revision === body.revision);\n moveEvents[body.bodyMoveIndex].fellAsleep = true;\n body.bodyMoveIndex = B2_NULL_INDEX;\n }\n\n const awakeBodyIndex = body.localIndex;\n console.assert(0 <= awakeBodyIndex && awakeBodyIndex < awakeSet.sims.count);\n\n const awakeSim = awakeSet.sims.data[awakeBodyIndex];\n\n const sleepBodyIndex = sleepSet.sims.count;\n const sleepBodySim = b2AddBodySim(sleepSet.sims);\n awakeSim.copyTo(sleepBodySim);\n\n // Object.assign(sleepBodySim, awakeSim);\n\n // console.warn(\"b \" + (world.solverSetArray[2].sims.data[0].transform != null));\n\n const movedIndex = b2RemoveBodySim(awakeSet.sims, awakeBodyIndex);\n\n // console.warn(\"movedIndex \" + movedIndex);\n\n // console.warn(\"b2 \" + (world.solverSetArray[2].sims.data[0].transform != null));\n console.assert(world.solverSetArray[2].sims.data[0].transform != null, \"1 transform is null\");\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = awakeSet.sims.data[awakeBodyIndex];\n const movedId = movedSim.bodyId;\n\n // b2CheckIndex(bodies, movedId);\n const movedBody = bodies[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = awakeBodyIndex;\n }\n\n b2RemoveBodyState(awakeSet.states, awakeBodyIndex);\n\n body.setIndex = sleepSetId;\n body.localIndex = sleepBodyIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n\n console.assert(contact.setIndex === b2SetType.b2_awakeSet || contact.setIndex === b2SetType.b2_disabledSet);\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0);\n\n continue;\n }\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(bodies, otherBodyId);\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n continue;\n }\n\n const localIndex = contact.localIndex;\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n const contactSim = awakeSet.contacts.data[localIndex];\n\n console.assert(contactSim.manifold.pointCount === 0);\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0 || (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0);\n\n contact.setIndex = b2SetType.b2_disabledSet;\n contact.localIndex = disabledSet.contacts.count;\n const disabledContactSim = b2AddContact(disabledSet.contacts);\n disabledContactSim.set(contactSim);\n\n const movedContactIndex = b2RemoveContact(awakeSet.contacts, localIndex);\n\n if (movedContactIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = awakeSet.contacts.data[localIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n console.assert(contacts[movedId].localIndex === movedContactIndex);\n contacts[movedId].localIndex = localIndex;\n }\n }\n\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(contacts, contactId);\n const contact = contacts[contactId];\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.islandId === islandId);\n const colorIndex = contact.colorIndex;\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, contact.edges[0].bodyId);\n b2ClearBit(color.bodySet, contact.edges[1].bodyId);\n }\n\n const awakeContactIndex = contact.localIndex;\n console.assert(0 <= awakeContactIndex && awakeContactIndex < color.contacts.count);\n const awakeContactSim = color.contacts.data[awakeContactIndex];\n\n const sleepContactIndex = sleepSet.contacts.count;\n const sleepContactSim = b2AddContact(sleepSet.contacts);\n sleepContactSim.set(awakeContactSim);\n\n const movedIndex = b2RemoveContact(color.contacts, awakeContactIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = color.contacts.data[awakeContactIndex];\n const movedId = movedContactSim.contactId;\n\n // b2CheckIndex(contacts, movedId);\n const movedContact = contacts[movedId];\n console.assert(movedContact.localIndex === movedIndex);\n movedContact.localIndex = awakeContactIndex;\n }\n\n contact.setIndex = sleepSetId;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = sleepContactIndex;\n\n contactId = contact.islandNext;\n }\n\n const joints = world.jointArray;\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(joints, jointId);\n const joint = joints[jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.islandId === islandId);\n const colorIndex = joint.colorIndex;\n const localIndex = joint.localIndex;\n\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n const awakeJointSim = color.joints.data[localIndex];\n\n if (colorIndex !== b2_overflowIndex)\n {\n b2ClearBit(color.bodySet, joint.edges[0].bodyId);\n b2ClearBit(color.bodySet, joint.edges[1].bodyId);\n }\n\n const sleepJointIndex = sleepSet.joints.count;\n const sleepJointSim = b2AddJoint(sleepSet.joints);\n awakeJointSim.copyTo(sleepJointSim);\n\n const movedIndex = b2RemoveJoint(color.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = color.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(joints, movedId);\n const movedJoint = joints[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n\n joint.setIndex = sleepSetId;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = sleepJointIndex;\n\n jointId = joint.islandNext;\n }\n\n console.assert(island.setIndex === b2SetType.b2_awakeSet);\n\n const islandIndex = island.localIndex;\n const sleepIsland = b2AddIsland(sleepSet.islands);\n sleepIsland.islandId = islandId;\n\n const movedIslandIndex = b2RemoveIsland(awakeSet.islands, islandIndex);\n\n if (movedIslandIndex !== B2_NULL_INDEX)\n {\n const movedIslandSim = awakeSet.islands.data[islandIndex];\n const movedIslandId = movedIslandSim.islandId;\n\n // b2CheckIndex(world.islandArray, movedIslandId);\n const movedIsland = world.islandArray[movedIslandId];\n console.assert(movedIsland.localIndex === movedIslandIndex);\n movedIsland.localIndex = islandIndex;\n }\n\n island.setIndex = sleepSetId;\n island.localIndex = 0;\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2MergeSolverSets(world, setId1, setId2)\n{\n console.assert(setId1 >= b2SetType.b2_firstSleepingSet);\n console.assert(setId2 >= b2SetType.b2_firstSleepingSet);\n\n // b2CheckIndex(world.solverSetArray, setId1);\n // b2CheckIndex(world.solverSetArray, setId2);\n let set1 = world.solverSetArray[setId1];\n let set2 = world.solverSetArray[setId2];\n\n if (set1.sims.count < set2.sims.count)\n {\n [ set1, set2 ] = [ set2, set1 ];\n [ setId1, setId2 ] = [ setId2, setId1 ];\n }\n\n const bodies = world.bodyArray;\n const bodyCount = set2.sims.count;\n\n for (let i = 0; i < bodyCount; ++i)\n {\n const simSrc = set2.sims.data[i];\n\n const body = bodies[simSrc.bodyId];\n console.assert(body.setIndex === setId2);\n body.setIndex = setId1;\n body.localIndex = set1.sims.count;\n\n const simDst = b2AddBodySim(set1.sims);\n Object.assign(simDst, simSrc);\n }\n\n const contacts = world.contactArray;\n const contactCount = set2.contacts.count;\n\n for (let i = 0; i < contactCount; ++i)\n {\n const contactSrc = set2.contacts.data[i];\n\n const contact = contacts[contactSrc.contactId];\n console.assert(contact.setIndex === setId2);\n contact.setIndex = setId1;\n contact.localIndex = set1.contacts.count;\n\n const contactDst = b2AddContact(set1.contacts);\n contactDst.set(contactSrc);\n }\n\n const joints = world.jointArray;\n const jointCount = set2.joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const jointSrc = set2.joints.data[i];\n\n const joint = joints[jointSrc.jointId];\n console.assert(joint.setIndex === setId2);\n joint.setIndex = setId1;\n joint.localIndex = set1.joints.count;\n\n const jointDst = b2AddJoint(set1.joints);\n Object.assign(jointDst, jointSrc);\n }\n\n const islands = world.islandArray;\n const islandCount = set2.islands.count;\n\n for (let i = 0; i < islandCount; ++i)\n {\n const islandSrc = set2.islands.data[i];\n const islandId = islandSrc.islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n island.setIndex = setId1;\n island.localIndex = set1.islands.count;\n\n const islandDst = b2AddIsland(set1.islands);\n Object.assign(islandDst, islandSrc);\n }\n\n b2DestroySolverSet(world, setId2);\n\n b2ValidateSolverSets(world);\n}\n\nexport function b2TransferBody(world, targetSet, sourceSet, body)\n{\n console.assert(targetSet !== sourceSet);\n\n const sourceIndex = body.localIndex;\n console.assert(0 <= sourceIndex && sourceIndex <= sourceSet.sims.count);\n const sourceSim = sourceSet.sims.data[sourceIndex];\n\n const targetIndex = targetSet.sims.count;\n const targetSim = b2AddBodySim(targetSet.sims);\n Object.assign(targetSim, sourceSim);\n\n const movedIndex = b2RemoveBodySim(sourceSet.sims, sourceIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedSim = sourceSet.sims.data[sourceIndex];\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = sourceIndex;\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveBodyState(sourceSet.states, sourceIndex);\n }\n else if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n const state = b2AddBodyState(targetSet.states);\n Object.assign(state, new b2BodyState());\n }\n\n body.setIndex = targetSet.setIndex;\n body.localIndex = targetIndex;\n}\n\nexport function b2TransferJoint(world, targetSet, sourceSet, joint)\n{\n console.assert(targetSet !== sourceSet);\n\n const localIndex = joint.localIndex;\n const colorIndex = joint.colorIndex;\n\n let sourceSim;\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[colorIndex];\n\n console.assert(0 <= localIndex && localIndex < color.joints.count);\n sourceSim = color.joints.data[localIndex];\n }\n else\n {\n console.assert(colorIndex === B2_NULL_INDEX);\n console.assert(0 <= localIndex && localIndex < sourceSet.joints.count);\n sourceSim = sourceSet.joints.data[localIndex];\n }\n\n if (targetSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2AddJointToGraph(world, sourceSim, joint);\n joint.setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n joint.setIndex = targetSet.setIndex;\n joint.localIndex = targetSet.joints.count;\n joint.colorIndex = B2_NULL_INDEX;\n\n const targetSim = b2AddJoint(targetSet.joints);\n Object.assign(targetSim, sourceSim);\n }\n\n if (sourceSet.setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, colorIndex, localIndex);\n }\n else\n {\n const movedIndex = b2RemoveJoint(sourceSet.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedJointSim = sourceSet.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n\n // b2CheckIndex(world.jointArray, movedId);\n const movedJoint = world.jointArray[movedId];\n movedJoint.localIndex = localIndex;\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport * as bitset_h from './include/bitset_h.js';\nimport * as body_h from './include/body_h.js';\nimport * as constraint_graph_h from './include/constraint_graph_h.js';\nimport * as contact_solver_h from './include/contact_solver_h.js';\nimport * as core_h from './include/core_h.js';\nimport * as joint_h from './include/joint_h.js';\nimport * as shape_h from './include/shape_h.js';\n\nimport { B2_DEFAULT_MASK_BITS, b2Manifold, b2Sweep, b2TOIInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport {\n B2_PI,\n b2AABB,\n b2AABB_Contains,\n b2AABB_Union,\n b2IntegrateRotationOut,\n b2InvMagRot,\n b2IsValid,\n b2Length,\n b2Lerp,\n b2MulRotC,\n b2MulRotS,\n b2NLerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { B2_PROXY_ID, B2_PROXY_TYPE, b2BroadPhase_EnlargeProxy, b2BufferMove } from './include/broad_phase_h.js';\nimport { b2AllocateStackItem, b2FreeStackItem } from './include/stack_allocator_h.js';\nimport { b2BodyId, b2ShapeId } from './include/id_h.js';\nimport { b2BodyMoveEvent, b2BodyType, b2ContactHitEvent, b2ShapeType } from './include/types_h.js';\nimport { b2ContactSimFlags, b2ShouldShapesCollide } from './include/contact_h.js';\nimport { b2DynamicTree_EnlargeProxy, b2DynamicTree_Query } from './include/dynamic_tree_h.js';\nimport { b2GetSweepTransform, b2MakeProxy, b2TimeOfImpact } from './include/distance_h.js';\nimport { b2MergeAwakeIslands, b2SplitIsland } from './include/island_h.js';\nimport { b2SetType, b2ValidateSolverSets, b2_maxWorkers } from './include/world_h.js';\n\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2ComputeManifold } from './contact_c.js';\nimport { b2TrySleepIsland } from './include/solver_set_h.js';\n\n/**\n * @namespace Solver\n */\n\nexport const b2SolverStageType = {\n b2_stagePrepareJoints: 0,\n b2_stagePrepareContacts: 1,\n b2_stageIntegrateVelocities: 2,\n b2_stageWarmStart: 3,\n b2_stageSolve: 4,\n b2_stageIntegratePositions: 5,\n b2_stageRelax: 6,\n b2_stageRestitution: 7,\n b2_stageStoreImpulses: 8\n};\n\nexport const b2SolverBlockType = {\n b2_bodyBlock: 0,\n b2_jointBlock: 1,\n b2_contactBlock: 2,\n b2_graphJointBlock: 3,\n b2_graphContactBlock: 4\n};\n\nexport class b2SolverBlock\n{\n constructor()\n {\n this.startIndex = 0;\n this.count = 0;\n this.blockType = 0;\n this.syncIndex = 0;\n \n }\n}\n\nexport class b2SolverStage\n{\n constructor()\n {\n this.type = 0;\n this.blocks = null;\n this.blockCount = 0;\n this.colorIndex = 0;\n this.completionCount = 0;\n \n }\n}\n\nexport class b2WorkerContext\n{\n constructor()\n {\n this.context = new b2StepContext();\n this.workerIndex = 0;\n this.userTask = null;\n \n }\n}\n\nexport class b2Softness\n{\n constructor(biasRate = 0, massScale = 0, impulseScale = 0)\n {\n this.biasRate = biasRate;\n this.massScale = massScale;\n this.impulseScale = impulseScale;\n }\n\n clone()\n {\n return new b2Softness(this.biasRate, this.massScale, this.impulseScale);\n }\n}\n\nexport class b2StepContext\n{\n constructor()\n {\n this.dt = 0;\n this.inv_dt = 0;\n this.h = 0;\n this.inv_h = 0;\n this.subStepCount = 0;\n this.jointSoftness = new b2Softness(0, 0, 0);\n this.contactSoftness = new b2Softness(0, 0, 0);\n this.staticSoftness = new b2Softness(0, 0, 0);\n this.restitutionThreshold = 0;\n this.maxLinearVelocity = 0;\n this.world = null;\n this.graph = null;\n this.states = null;\n this.sims = null;\n this.enlargedShapes = null;\n this.enlargedShapeCount = 0;\n this.fastBodies = null;\n this.fastBodyCount = 0;\n this.bulletBodies = null;\n this.bulletBodyCount = 0;\n this.joints = null;\n this.contacts = null;\n this.simdContactConstraints = null;\n this.activeColorCount = 0;\n this.workerCount = 0;\n this.stages = null;\n this.stageCount = 0;\n this.enableWarmStarting = false;\n this.atomicSyncBits = 0;\n \n }\n}\n\nexport function b2MakeSoft(hertz, zeta, h)\n{\n if (hertz === 0.0)\n {\n return new b2Softness(0.0, 1.0, 0.0);\n }\n\n const omega = 2.0 * B2_PI * hertz;\n const a1 = 2.0 * zeta + h * omega;\n const a2 = h * omega * a1;\n const a3 = 1.0 / (1.0 + a2);\n\n return new b2Softness(omega / a1, a2 * a3, a3);\n}\n\n\n// Integrate velocities and apply damping\nfunction b2IntegrateVelocitiesTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const sims = context.sims;\n\n const gravity = context.world.gravity;\n const h = context.h;\n const maxLinearSpeed = context.maxLinearVelocity;\n const maxAngularSpeed = core_h.B2_MAX_ROTATION * context.inv_dt;\n const maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;\n const maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const sim = sims[i];\n const state = states[i];\n\n const v = state.linearVelocity; // .clone();\n let w = state.angularVelocity;\n\n // Apply forces, torque, gravity, and damping\n // Apply damping.\n // Differential equation: dv/dt + c * v = 0\n // Solution: v(t) = v0 * exp(-c * t)\n // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v(t) * exp(-c * dt)\n // v2 = exp(-c * dt) * v1\n // Pade approximation:\n // v2 = v1 * 1 / (1 + c * dt)\n const linearDamping = 1.0 / (1.0 + h * sim.linearDamping);\n const angularDamping = 1.0 / (1.0 + h * sim.angularDamping);\n\n // const linearVelocityDelta = b2MulSV(h * sim.invMass, b2MulAdd(sim.force, sim.mass * sim.gravityScale, gravity));\n const m = sim.mass * sim.gravityScale;\n const im = h * sim.invMass;\n const lvdX = im * (sim.force.x + m * gravity.x);\n const lvdY = im * (sim.force.y + m * gravity.y);\n const angularVelocityDelta = h * sim.invInertia * sim.torque;\n\n // v = b2MulAdd(linearVelocityDelta, linearDamping, v);\n v.x = lvdX + linearDamping * v.x;\n v.y = lvdY + linearDamping * v.y;\n w = angularVelocityDelta + angularDamping * w;\n\n // Clamp to max linear speed\n // b2Dot(v, v)\n const l = v.x * v.x + v.y * v.y;\n\n if (l > maxLinearSpeedSquared)\n {\n const ratio = maxLinearSpeed / Math.sqrt(l); // b2Length(v);\n // v = b2MulSV(ratio, v);\n v.x *= ratio;\n v.y *= ratio;\n sim.isSpeedCapped = true;\n }\n\n // Clamp to max angular speed\n if (w * w > maxAngularSpeedSquared && sim.allowFastRotation === false)\n {\n const ratio = maxAngularSpeed / Math.abs(w);\n w *= ratio;\n sim.isSpeedCapped = true;\n }\n\n state.linearVelocity = v;\n state.angularVelocity = w;\n }\n}\n\n// PJB: 19/11/2024 another unused function (SIMD related?)\n\n/**\nfunction b2PrepareJointsTask(startIndex, endIndex, context)\n{\n const joints = context.joints;\n\n for (let i = startIndex; i < endIndex; ++i) {\n const joint = joints[i];\n joint_h.b2PrepareJoint(joint, context);\n }\n}\n*/\n\nfunction b2IntegratePositionsTask(startIndex, endIndex, context)\n{\n const states = context.states;\n const h = context.h;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const state = states[i];\n\n // state.deltaRotation = b2IntegrateRotation(state.deltaRotation, h * state.angularVelocity);\n b2IntegrateRotationOut(state.deltaRotation, h * state.angularVelocity, state.deltaRotation);\n\n // state.deltaPosition = b2MulAdd(state.deltaPosition, h, state.linearVelocity);\n state.deltaPosition.x = state.deltaPosition.x + h * state.linearVelocity.x;\n state.deltaPosition.y = state.deltaPosition.y + h * state.linearVelocity.y;\n console.assert(state.deltaPosition != null);\n }\n}\n\nfunction b2FinalizeBodiesTask(startIndex, endIndex, threadIndex, context)\n{\n const stepContext = context;\n const world = stepContext.world;\n const enableSleep = world.enableSleep;\n const states = stepContext.states;\n const sims = stepContext.sims;\n const bodies = world.bodyArray;\n const timeStep = stepContext.dt;\n const invTimeStep = stepContext.inv_dt;\n\n const worldId = world.worldId;\n const moveEvents = world.bodyMoveEventArray;\n\n const islands = world.islandArray;\n\n const enlargedSimBitSet = world.taskContextArray[threadIndex].enlargedSimBitSet;\n const awakeIslandBitSet = world.taskContextArray[threadIndex].awakeIslandBitSet;\n const taskContext = world.taskContextArray[threadIndex];\n\n const enableContinuous = world.enableContinuous;\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n console.assert(startIndex <= endIndex);\n\n for (let simIndex = startIndex; simIndex < endIndex; ++simIndex)\n {\n const state = states[simIndex];\n const sim = sims[simIndex];\n\n const v = state.linearVelocity;\n const w = state.angularVelocity;\n\n console.assert(b2IsValid(v.x) && b2IsValid(v.y));\n console.assert(Number.isFinite(w));\n sim.center.x += state.deltaPosition.x;\n sim.center.y += state.deltaPosition.y;\n\n const c = b2MulRotC(state.deltaRotation, sim.transform.q);\n const s = b2MulRotS(state.deltaRotation, sim.transform.q);\n const im = b2InvMagRot(c, s);\n\n // sim.transform.q.c = im * c; //b2NormalizeRot(b2MulRot(state.deltaRotation, sim.transform.q));\n // sim.transform.q.s = im * s;\n sim.transform.q = new b2Rot(im * c, im * s); // PJB: REQUIRES a new b2Rot here to prevent breaking tests e.g. \"drive\"\n\n const maxVelocity = b2Length(v) + Math.abs(w) * sim.maxExtent;\n\n const maxDeltaPosition = b2Length(state.deltaPosition) + Math.abs(state.deltaRotation.s) * sim.maxExtent;\n\n const positionSleepFactor = 0.5;\n\n const sleepVelocity = Math.max(maxVelocity, positionSleepFactor * invTimeStep * maxDeltaPosition);\n\n state.deltaPosition.x = 0; // new b2Vec2(0, 0);\n state.deltaPosition.y = 0;\n state.deltaRotation.c = 1; // new b2Rot(1, 0);\n state.deltaRotation.s = 0;\n\n sim.transform.p.x = sim.center.x - (sim.transform.q.c * sim.localCenter.x - sim.transform.q.s * sim.localCenter.y); // b2Sub(sim.center, b2RotateVector(sim.transform.q, sim.localCenter));\n sim.transform.p.y = sim.center.y - (sim.transform.q.s * sim.localCenter.x + sim.transform.q.c * sim.localCenter.y);\n\n const body = bodies[sim.bodyId];\n body.bodyMoveIndex = simIndex;\n moveEvents[simIndex].transform = sim.transform;\n moveEvents[simIndex].bodyId = new b2BodyId(sim.bodyId + 1, worldId, body.revision); // { id: sim.bodyId + 1, worldId: worldId, revision: body.revision };\n moveEvents[simIndex].userData = body.userData;\n moveEvents[simIndex].fellAsleep = false;\n\n sim.force.x = 0; // new b2Vec2(0, 0);\n sim.force.y = 0;\n sim.torque = 0.0;\n\n body.isSpeedCapped = sim.isSpeedCapped;\n sim.isSpeedCapped = false;\n\n sim.isFast = false;\n\n if (enableSleep === false || body.enableSleep === false || sleepVelocity > body.sleepThreshold)\n {\n body.sleepTime = 0.0;\n\n const safetyFactor = 0.5;\n\n if (body.type === b2BodyType.b2_dynamicBody && enableContinuous && maxVelocity * timeStep > safetyFactor * sim.minExtent)\n {\n if (sim.isBullet)\n {\n stepContext.bulletBodyCount++;\n stepContext.bulletBodies[stepContext.bulletBodyCount - 1] = simIndex;\n }\n else\n {\n stepContext.fastBodyCount++;\n stepContext.fastBodies[stepContext.fastBodyCount - 1] = simIndex;\n }\n\n sim.isFast = true;\n }\n else\n {\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n }\n }\n else\n {\n // console.warn(\"sleeping \" + body.setIndex + \" \" + body.id);\n sim.center0X = sim.center.x;\n sim.center0Y = sim.center.y;\n sim.rotation0.x = sim.transform.q.x;\n sim.rotation0.y = sim.transform.q.y;\n body.sleepTime += timeStep;\n }\n\n // b2CheckIndex(islands, body.islandId);\n const island = islands[body.islandId];\n\n if (body.sleepTime < core_h.b2_timeToSleep)\n {\n const islandIndex = island.localIndex;\n bitset_h.b2SetBit(awakeIslandBitSet, islandIndex);\n }\n else if (island.constraintRemoveCount > 0)\n {\n if (body.sleepTime > taskContext.splitSleepTime)\n {\n taskContext.splitIslandId = body.islandId;\n taskContext.splitSleepTime = body.sleepTime;\n }\n }\n\n const transform = sim.transform;\n const isFast = sim.isFast;\n let shapeId = body.headShapeId;\n\n while (shapeId !== core_h.B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n console.assert(shape.isFast === false);\n\n if (isFast)\n {\n shape.isFast = true;\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n else\n {\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n console.assert(shape.enlargedAABB === false);\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n\n bitset_h.b2SetBit(enlargedSimBitSet, simIndex);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nfunction b2ExecuteBlock(stage, context, block)\n{\n const stageType = stage.type;\n const startIndex = block.startIndex;\n const endIndex = startIndex + block.count;\n\n if (stageType === b2SolverStageType.b2_stageIntegrateVelocities)\n {\n b2IntegrateVelocitiesTask(startIndex, endIndex, context);\n }\n else if (stageType === b2SolverStageType.b2_stageIntegratePositions)\n {\n b2IntegratePositionsTask(startIndex, endIndex, context);\n }\n else\n {\n /*\n console.log(\"block stage \" + [\n \"b2_stagePrepareJoints: 0\",\n \"b2_stagePrepareContacts: 1\",\n \"b2_stageIntegrateVelocities: 2\",\n \"b2_stageWarmStart: 3\",\n \"b2_stageSolve: 4\",\n \"b2_stageIntegratePositions: 5\",\n \"b2_stageRelax: 6\",\n \"b2_stageRestitution: 7\",\n \"b2_stageStoreImpulses: 8\"\n ][stageType]);\n */\n\n console.warn(\"unsupported stage type: \" + stageType);\n }\n\n // PJB: many of these stages handle SIMD data preparation or processing, all of which has been removed for the JS translation\n // RD: Swapped for faster if/else block above\n}\n\nfunction b2ExecuteMainStage(stage, context)\n{\n // PJB: we're not multi-threading for the JS, we simply iterate the work blocks (0..4 seems typical)\n const blockCount = stage.blockCount;\n\n for (let i = 0; i < blockCount; i++)\n {\n b2ExecuteBlock(stage, context, stage.blocks[i]);\n }\n}\n\nexport function b2SolverTask(workerContext)\n{\n const workerIndex = workerContext.workerIndex;\n const context = workerContext.context;\n const activeColorCount = context.activeColorCount;\n const stages = context.stages;\n\n if (workerIndex === 0)\n {\n // let bodySyncIndex = 1; // un-used except in debugging\n let stageIndex = 0;\n\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // unused except for debugging\n // let contactSyncIndex = 1;\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n b2ExecuteMainStage(stages[stageIndex], context);\n stageIndex += 1;\n\n // contactSyncIndex += 1;\n\n // unused except for debugging\n // let graphSyncIndex = 1;\n\n joint_h.b2PrepareOverflowJoints(context);\n contact_solver_h.b2PrepareOverflowContacts(context);\n\n const subStepCount = context.subStepCount;\n\n for (let i = 0; i < subStepCount; ++i)\n {\n let iterStageIndex = stageIndex;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n joint_h.b2WarmStartOverflowJoints(context);\n contact_solver_h.b2WarmStartOverflowContacts(context);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n let useBias = true;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n\n // syncBits = (bodySyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n\n // bodySyncIndex += 1;\n\n useBias = false;\n joint_h.b2SolveOverflowJoints(context, useBias);\n contact_solver_h.b2SolveOverflowContacts(context, useBias);\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n\n // graphSyncIndex += 1;\n }\n\n stageIndex += 1 + activeColorCount + activeColorCount + 1 + activeColorCount;\n\n {\n contact_solver_h.b2ApplyOverflowRestitution(context);\n\n let iterStageIndex = stageIndex;\n\n for (let colorIndex = 0; colorIndex < activeColorCount; ++colorIndex)\n {\n // syncBits = (graphSyncIndex << 16) | iterStageIndex;\n b2ExecuteMainStage(stages[iterStageIndex], context);\n iterStageIndex += 1;\n }\n stageIndex += activeColorCount;\n }\n\n contact_solver_h.b2StoreOverflowImpulses(context);\n\n // syncBits = (contactSyncIndex << 16) | stageIndex;\n console.assert( stages[stageIndex].type == b2SolverStageType.b2_stageStoreImpulses );\n b2ExecuteMainStage(stages[stageIndex], context);\n\n context.atomicSyncBits = Number.MAX_SAFE_INTEGER;\n console.assert( stageIndex + 1 == context.stageCount );\n\n return;\n }\n\n console.error(\"b2SolverTask workerIndex = \" + workerIndex);\n}\n\nconst constSweep = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\nexport function b2ContinuousQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const continuousContext = context;\n const fastShape = continuousContext.fastShape;\n const fastBodySim = continuousContext.fastBodySim;\n\n // skip same shape\n if (shapeId === fastShape.id)\n {\n return true;\n }\n\n const world = continuousContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // skip same body\n if (shape.bodyId === fastShape.bodyId)\n {\n return true;\n }\n\n // skip sensors\n if (shape.isSensor === true)\n {\n return true;\n }\n\n // skip filtered shapes\n let canCollide = b2ShouldShapesCollide(fastShape.filter, shape.filter);\n\n if (canCollide === false)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = body_h.b2GetBodySim(world, body);\n console.assert(body.type === b2BodyType.b2_staticBody || fastBodySim.isBullet);\n\n if (bodySim.isBullet)\n {\n return true;\n }\n\n // b2CheckIndex(world.bodyArray, fastBodySim.bodyId);\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n canCollide = body_h.b2ShouldBodiesCollide(world, fastBody, body);\n\n if (canCollide === false)\n {\n return true;\n }\n\n const customFilterFcn = world.customFilterFcn;\n\n if (customFilterFcn != null)\n {\n const idA = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const idB = new b2ShapeId(fastShape.id + 1, world.worldId, fastShape.revision);\n canCollide = customFilterFcn(idA, idB, world.customFilterContext);\n\n if (canCollide === false)\n {\n return true;\n }\n }\n\n if (shape.type === b2ShapeType.b2_chainSegmentShape)\n {\n const transform = bodySim.transform;\n const p1 = b2TransformPoint(transform, shape.chainSegment.segment.point1);\n const p2 = b2TransformPoint(transform, shape.chainSegment.segment.point2);\n\n // let e = b2Sub(p2, p1);\n const eX = p2.x - p1.x;\n const eY = p2.y - p1.y;\n const c1X = continuousContext.centroid1X;\n const c1Y = continuousContext.centroid1Y;\n const c2X = continuousContext.centroid2X;\n const c2Y = continuousContext.centroid2Y;\n\n // let offset1 = b2Cross(b2Sub(c1, p1), e);\n let dx = c1X - p1.x;\n let dy = c1Y - p1.y;\n const offset1 = dx * eY - dy * eX;\n\n // let offset2 = b2Cross(b2Sub(c2, p1), e);\n dx = c2X - p1.x;\n dy = c2Y - p1.y;\n const offset2 = dx * eY - dy * eX;\n\n if (offset1 < 0.0 || offset2 > 0.0)\n {\n return true;\n }\n }\n\n const input = new b2TOIInput();\n input.proxyA = shape_h.b2MakeShapeDistanceProxy(shape);\n input.proxyB = shape_h.b2MakeShapeDistanceProxy(fastShape);\n input.sweepA = body_h.b2MakeSweep(bodySim, constSweep);\n input.sweepB = continuousContext.sweep;\n input.tMax = continuousContext.fraction;\n\n let hitFraction = continuousContext.fraction;\n\n let didHit = false;\n let output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n else if (0.0 === output.t)\n {\n const centroid = shape_h.b2GetShapeCentroid(fastShape);\n input.proxyB = b2MakeProxy([ centroid ], 1, core_h.b2_speculativeDistance);\n output = b2TimeOfImpact(input);\n\n if (0.0 < output.t && output.t < continuousContext.fraction)\n {\n hitFraction = output.t;\n didHit = true;\n }\n }\n\n if (didHit && (shape.enablePreSolveEvents || fastShape.enablePreSolveEvents))\n {\n // Pre-solve is expensive because I need to compute a temporary manifold\n const transformA = b2GetSweepTransform( input.sweepA, hitFraction );\n const transformB = b2GetSweepTransform( input.sweepB, hitFraction );\n const manifold = new b2Manifold();\n b2ComputeManifold( shape, transformA, fastShape, transformB, manifold );\n const shapeIdA = new b2ShapeId( shape.id + 1, world.worldId, shape.revision );\n const shapeIdB = new b2ShapeId( fastShape.id + 1, world.worldId, fastShape.revision );\n\n // The user may modify the temporary manifold here but it doesn't matter. They will be able to\n // modify the real manifold in the discrete solver.\n didHit = world.preSolveFcn( shapeIdA, shapeIdB, manifold, world.preSolveContext );\n }\n\n if (didHit)\n {\n continuousContext.fraction = hitFraction;\n }\n\n return true;\n}\n\nclass b2ContinuousContext\n{\n constructor()\n {\n this.world = null;\n this.fastBodySim = null;\n this.fastShape = null;\n this.centroid1X = 0;\n this.centroid1Y = 0;\n this.centroid2X = 0;\n this.centroid2Y = 0;\n this.sweep = null;\n this.fraction = 0.0;\n }\n}\n\nconst p = new b2Vec2();\nconst p1 = new b2Vec2();\nconst constSweep2 = new b2Sweep(new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Rot(), new b2Rot());\n\n// Continuous collision of dynamic versus static\nexport function b2SolveContinuous(world, bodySimIndex)\n{\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= bodySimIndex && bodySimIndex < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[bodySimIndex];\n console.assert(fastBodySim.isFast);\n\n const shapes = world.shapeArray;\n\n const sweep = body_h.b2MakeSweep(fastBodySim, constSweep2);\n\n // let xf1 = new b2Transform(b2Sub(sweep.c1, b2RotateVector(sweep.q1, sweep.localCenter)), sweep.q1);\n p.x = sweep.c1.x - (sweep.q1.c * sweep.localCenter.x - sweep.q1.s * sweep.localCenter.y);\n p.y = sweep.c1.y - (sweep.q1.s * sweep.localCenter.x + sweep.q1.c * sweep.localCenter.y);\n const xf1 = new b2Transform(p, sweep.q1);\n\n // let xf2 = new b2Transform(b2Sub(sweep.c2, b2RotateVector(sweep.q2, sweep.localCenter)), sweep.q2);\n p1.x = sweep.c2.x - (sweep.q2.c * sweep.localCenter.x - sweep.q2.s * sweep.localCenter.y);\n p1.y = sweep.c2.y - (sweep.q2.s * sweep.localCenter.x + sweep.q2.c * sweep.localCenter.y);\n const xf2 = new b2Transform(p1, sweep.q2);\n\n const staticTree = world.broadPhase.trees[b2BodyType.b2_staticBody];\n const kinematicTree = world.broadPhase.trees[b2BodyType.b2_kinematicBody];\n const dynamicTree = world.broadPhase.trees[b2BodyType.b2_dynamicBody];\n const fastBody = world.bodyArray[fastBodySim.bodyId];\n\n const context = new b2ContinuousContext();\n context.world = world;\n context.sweep = sweep;\n context.fastBodySim = fastBodySim;\n context.fraction = 1.0;\n\n const isBullet = fastBodySim.isBullet;\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const fastShape = shapes[shapeId];\n console.assert(fastShape.isFast == true);\n\n shapeId = fastShape.nextShapeId;\n\n // Clear flag (keep set on body)\n fastShape.isFast = false;\n\n context.fastShape = fastShape;\n\n // context.centroid1 = b2TransformPoint(xf1, fastShape.localCentroid);\n b2TransformPointOut(xf1, fastShape.localCentroid, p);\n context.centroid1X = p.x;\n context.centroid1Y = p.y;\n\n // context.centroid2 = b2TransformPoint(xf2, fastShape.localCentroid);\n b2TransformPointOut(xf2, fastShape.localCentroid, p);\n context.centroid2X = p.x;\n context.centroid2Y = p.y;\n\n const box1 = fastShape.aabb;\n const box2 = shape_h.b2ComputeShapeAABB(fastShape, xf2);\n const box = b2AABB_Union(box1, box2);\n\n // Store this for later\n fastShape.aabb = box2;\n\n // No continuous collision for sensors\n if (fastShape.isSensor)\n {\n continue;\n }\n\n b2DynamicTree_Query(staticTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n\n if (isBullet)\n {\n b2DynamicTree_Query(kinematicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n b2DynamicTree_Query(dynamicTree, box, B2_DEFAULT_MASK_BITS, b2ContinuousQueryCallback, context);\n }\n }\n\n const speculativeDistance = core_h.b2_speculativeDistance;\n const aabbMargin = core_h.b2_aabbMargin;\n\n if (context.fraction < 1.0)\n {\n // Handle time of impact event\n const q = b2NLerp(sweep.q1, sweep.q2, context.fraction);\n const c = b2Lerp(sweep.c1, sweep.c2, context.fraction);\n const origin = b2Sub(c, b2RotateVector(q, sweep.localCenter));\n\n // Advance body\n const transform = new b2Transform(origin, q);\n fastBodySim.transform = transform;\n fastBodySim.center = c;\n fastBodySim.rotation0 = q;\n fastBodySim.center0X = c.x;\n fastBodySim.center0Y = c.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // Must recompute aabb at the interpolated transform\n const aabb = shape_h.b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (!b2AABB_Contains(shape.fatAABB, aabb))\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - aabbMargin, aabb.lowerBoundY - aabbMargin,\n aabb.upperBoundX + aabbMargin, aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n // No time of impact event\n\n // Advance body\n fastBodySim.rotation0 = fastBodySim.transform.q;\n fastBodySim.center0X = fastBodySim.center.x;\n fastBodySim.center0Y = fastBodySim.center.y;\n\n // Prepare AABBs for broad-phase\n shapeId = fastBody.headShapeId;\n\n while (shapeId != B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n // shape.aabb is still valid\n\n if (!b2AABB_Contains(shape.fatAABB, shape.aabb))\n {\n const fatAABB = new b2AABB(shape.aabb.lowerBoundX - aabbMargin, shape.aabb.lowerBoundY - aabbMargin,\n shape.aabb.upperBoundX + aabbMargin, shape.aabb.upperBoundY + aabbMargin);\n shape.fatAABB = fatAABB;\n\n shape.enlargedAABB = true;\n fastBodySim.enlargeAABB = true;\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n}\n\nexport function b2FastBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.fastBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\nexport function b2BulletBodyTask(startIndex, endIndex, taskContext)\n{\n // B2_MAYBE_UNUSED(threadIndex);\n\n const stepContext = taskContext;\n\n console.assert(startIndex <= endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const simIndex = stepContext.bulletBodies[i];\n b2SolveContinuous(stepContext.world, simIndex);\n }\n}\n\n// Solve with graph coloring\nexport function b2Solve(world, stepContext)\n{\n // const timer = b2CreateTimer();\n\n world.stepIndex += 1;\n\n b2MergeAwakeIslands(world);\n\n // world.profile.buildIslands = b2GetMillisecondsAndReset(timer);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const awakeBodyCount = awakeSet.sims.count;\n\n if (awakeBodyCount === 0)\n {\n // b2ValidateNoEnlarged(world.broadPhase);\n return;\n }\n\n // Prepare buffers for continuous collision (fast bodies)\n stepContext.fastBodyCount = 0;\n stepContext.fastBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"fast bodies\");\n stepContext.bulletBodyCount = 0;\n stepContext.bulletBodies = b2AllocateStackItem(world.stackAllocator, awakeBodyCount, \"bullet bodies\");\n\n // Solve constraints using graph coloring\n {\n const graph = world.constraintGraph;\n const colors = graph.colors;\n\n stepContext.sims = awakeSet.sims.data;\n stepContext.states = awakeSet.states.data;\n\n // count contacts, joints, and colors\n // let awakeContactCount = 0;\n let awakeJointCount = 0;\n let activeColorCount = 0;\n\n for (let i = 0; i < b2_graphColorCount - 1; ++i)\n {\n const perColorContactCount = colors[i].contacts.count;\n const perColorJointCount = colors[i].joints.count;\n const occupancyCount = perColorContactCount + perColorJointCount;\n activeColorCount += occupancyCount > 0 ? 1 : 0;\n\n // awakeContactCount += perColorContactCount;\n awakeJointCount += perColorJointCount;\n }\n\n // Deal with void**\n {\n const bodyMoveEventArray = world.bodyMoveEventArray;\n\n // b2Array_Resize(bodyMoveEventArray, awakeBodyCount);\n // if (bodyMoveEventArray.length < awakeBodyCount) {\n while (bodyMoveEventArray.length < awakeBodyCount)\n {\n bodyMoveEventArray.push(new b2BodyMoveEvent());\n }\n\n // }\n }\n\n const workerCount = world.workerCount;\n const blocksPerWorker = 4;\n const maxBlockCount = blocksPerWorker * workerCount;\n\n // PJB TODO: is ANY of this parallel stuff used in the JS? It should all be handled by 'overflow' cases...\n\n // Configure blocks for tasks that parallel-for bodies\n let bodyBlockSize = 1 << 5;\n let bodyBlockCount;\n\n if (awakeBodyCount > bodyBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n bodyBlockSize = Math.floor(awakeBodyCount / maxBlockCount);\n bodyBlockCount = maxBlockCount;\n }\n else\n {\n bodyBlockCount = Math.floor((awakeBodyCount - 1) >> 5) + 1;\n }\n\n // Configure blocks for tasks parallel-for each active graph color\n // The blocks are a mix of SIMD contact blocks and joint blocks\n\n const colorContactCounts = new Array(b2_graphColorCount);\n const colorContactBlockSizes = new Array(b2_graphColorCount);\n const colorContactBlockCounts = new Array(b2_graphColorCount);\n\n const colorJointCounts = new Array(b2_graphColorCount);\n const colorJointBlockSizes = new Array(b2_graphColorCount);\n const colorJointBlockCounts = new Array(b2_graphColorCount);\n\n const graphBlockCount = 0;\n const simdContactCount = 0;\n\n const overflowContactCount = colors[constraint_graph_h.b2_overflowIndex].contacts.count;\n const overflowContactConstraints = b2AllocateStackItem(\n world.stackAllocator,\n overflowContactCount,\n \"overflow contact constraint\",\n () => { return new contact_solver_h.b2ContactConstraint(); }\n );\n \n graph.colors[constraint_graph_h.b2_overflowIndex].overflowConstraints = overflowContactConstraints;\n\n // Define work blocks for preparing contacts and storing contact impulses\n let contactBlockSize = blocksPerWorker;\n let contactBlockCount = simdContactCount > 0 ? Math.floor((simdContactCount - 1) >> 2) + 1 : 0;\n\n if (simdContactCount > contactBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n contactBlockSize = Math.floor(simdContactCount / maxBlockCount);\n contactBlockCount = maxBlockCount;\n }\n\n // Define work blocks for preparing joints\n let jointBlockSize = blocksPerWorker;\n let jointBlockCount = awakeJointCount > 0 ? Math.floor((awakeJointCount - 1) >> 2) + 1 : 0;\n\n if (awakeJointCount > jointBlockSize * maxBlockCount)\n {\n // Too many blocks, increase block size\n jointBlockSize = Math.floor(awakeJointCount / maxBlockCount);\n jointBlockCount = maxBlockCount;\n }\n \n let stageCount = 0;\n\n // b2_stagePrepareJoints\n stageCount += 1;\n\n // b2_stagePrepareContacts\n stageCount += 1;\n\n // b2_stageIntegrateVelocities\n stageCount += 1;\n\n // b2_stageWarmStart\n stageCount += activeColorCount;\n\n // b2_stageSolve\n stageCount += activeColorCount;\n\n // b2_stageIntegratePositions\n stageCount += 1;\n\n // b2_stageRelax\n stageCount += activeColorCount;\n\n // b2_stageRestitution\n stageCount += activeColorCount;\n\n // b2_stageStoreImpulses\n stageCount += 1;\n\n const stages = Array.from({ length: stageCount }, () => new b2SolverStage()); // b2AllocateStackItem(world.stackAllocator, stageCount, \"stages\", () => { return new b2SolverStage(); });\n const bodyBlocks = b2AllocateStackItem(world.stackAllocator, bodyBlockCount, \"body blocks\");\n const contactBlocks = b2AllocateStackItem(world.stackAllocator, contactBlockCount, \"contact blocks\");\n const jointBlocks = b2AllocateStackItem(world.stackAllocator, jointBlockCount, \"joint blocks\");\n const graphBlocks = b2AllocateStackItem(world.stackAllocator, graphBlockCount, \"graph blocks\");\n\n // Split an awake island. This modifies:\n // - stack allocator\n // - world island array and solver set\n // - island indices on bodies, contacts, and joints\n if (world.splitIslandId != B2_NULL_INDEX)\n {\n b2SplitIsland(world, world.splitIslandId);\n }\n\n // Prepare body work blocks\n for (let i = 0; i < bodyBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * bodyBlockSize;\n block.count = bodyBlockSize;\n block.blockType = b2SolverBlockType.b2_bodyBlock;\n block.syncIndex = 0;\n bodyBlocks[i] = block;\n }\n bodyBlocks[bodyBlockCount - 1].count = awakeBodyCount - (bodyBlockCount - 1) * bodyBlockSize;\n\n // Prepare joint work blocks\n for (let i = 0; i < jointBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * jointBlockSize;\n block.count = jointBlockSize;\n block.blockType = b2SolverBlockType.b2_jointBlock;\n block.syncIndex = 0;\n jointBlocks[i] = block;\n }\n\n if (jointBlockCount > 0)\n {\n jointBlocks[jointBlockCount - 1].count = awakeJointCount - (jointBlockCount - 1) * jointBlockSize;\n }\n\n // Prepare contact work blocks\n for (let i = 0; i < contactBlockCount; ++i)\n {\n const block = new b2SolverBlock();\n block.startIndex = i * contactBlockSize;\n block.count = contactBlockSize;\n block.blockType = b2SolverBlockType.b2_contactBlock;\n block.syncIndex = 0;\n contactBlocks[i] = block;\n }\n\n if (contactBlockCount > 0)\n {\n contactBlocks[contactBlockCount - 1].count = simdContactCount - (contactBlockCount - 1) * contactBlockSize;\n }\n\n // Prepare graph work blocks\n const graphColorBlocks = new Array(b2_graphColorCount);\n let baseGraphBlock = 0; // Index into graphBlocks\n\n for (let i = 0; i < activeColorCount; ++i)\n {\n graphColorBlocks[i] = baseGraphBlock;\n const colorJointBlockCount = colorJointBlockCounts[i];\n const colorJointBlockSize = colorJointBlockSizes[i];\n\n for (let j = 0; j < colorJointBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorJointBlockSize;\n block.count = colorJointBlockSize;\n block.blockType = b2SolverBlockType.b2_graphJointBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorJointBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorJointBlockCount - 1].count =\n colorJointCounts[i] - (colorJointBlockCount - 1) * colorJointBlockSize;\n baseGraphBlock += colorJointBlockCount;\n }\n const colorContactBlockCount = colorContactBlockCounts[i];\n const colorContactBlockSize = colorContactBlockSizes[i];\n\n for (let j = 0; j < colorContactBlockCount; ++j)\n {\n const block = new b2SolverBlock();\n block.startIndex = j * colorContactBlockSize;\n block.count = colorContactBlockSize;\n block.blockType = b2SolverBlockType.b2_graphContactBlock;\n block.syncIndex = 0;\n graphBlocks[baseGraphBlock + j] = block;\n }\n\n if (colorContactBlockCount > 0)\n {\n graphBlocks[baseGraphBlock + colorContactBlockCount - 1].count =\n colorContactCounts[i] - (colorContactBlockCount - 1) * colorContactBlockSize;\n baseGraphBlock += colorContactBlockCount;\n }\n }\n const blockDiff = baseGraphBlock;\n console.assert(blockDiff === graphBlockCount, `Block count mismatch: ${blockDiff} !== ${graphBlockCount}`);\n\n // modified stage builder\n let si = 0;\n\n // Helper function to set stage properties\n const setStageProperties = (stage, type, blocks, blockCount, colorIndex = -1) =>\n {\n stage.type = type;\n stage.blocks = blocks;\n stage.blockCount = blockCount;\n stage.colorIndex = colorIndex;\n stage.completionCount = 0;\n };\n \n // Prepare joints\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareJoints, jointBlocks, jointBlockCount);\n\n // Prepare contacts\n setStageProperties(stages[si++], b2SolverStageType.b2_stagePrepareContacts, contactBlocks, contactBlockCount);\n\n // Integrate velocities\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegrateVelocities, bodyBlocks, bodyBlockCount);\n\n // Warm start\n /*\n console.log(\"activeColorCount \" + activeColorCount);\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageWarmStart,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Solve graph\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageSolve,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Integrate positions\n setStageProperties(stages[si++], b2SolverStageType.b2_stageIntegratePositions, bodyBlocks, bodyBlockCount);\n \n // Relax constraints\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRelax,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Restitution\n // Note: joint blocks mixed in, could have joint limit restitution\n /*\n for (let i = 0; i < activeColorCount; ++i) {\n setStageProperties(\n stages[si++],\n b2SolverStageType.b2_stageRestitution,\n graphBlocks.slice(graphColorBlocks[i], graphColorBlocks[i] + colorJointBlockCounts[i] + colorContactBlockCounts[i]),\n colorJointBlockCounts[i] + colorContactBlockCounts[i],\n activeColorIndices[i]\n );\n }\n */\n \n // Store impulses\n setStageProperties(stages[si++], b2SolverStageType.b2_stageStoreImpulses, contactBlocks, contactBlockCount);\n \n console.assert(si === stageCount, \"Stage count mismatch\");\n \n console.assert(workerCount <= b2_maxWorkers);\n\n stepContext.graph = graph;\n stepContext.joints = null; // joints;\n stepContext.contacts = null; // contacts;\n stepContext.simdContactConstraints = null; // simdContactConstraints;\n stepContext.activeColorCount = activeColorCount;\n stepContext.workerCount = workerCount;\n stepContext.stageCount = stageCount;\n stepContext.stages = stages;\n\n {\n const workerContext = new b2WorkerContext();\n workerContext.context = stepContext;\n workerContext.workerIndex = 0;\n b2SolverTask(workerContext);\n }\n\n world.splitIslandId = B2_NULL_INDEX;\n\n // Prepare contact, enlarged body, and island bit sets used in body finalization.\n const awakeIslandCount = awakeSet.islands.count;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n taskContext.enlargedSimBitSet = bitset_h.b2SetBitCountAndClear(taskContext.enlargedSimBitSet, awakeBodyCount);\n taskContext.awakeIslandBitSet = bitset_h.b2SetBitCountAndClear(taskContext.awakeIslandBitSet, awakeIslandCount);\n taskContext.splitIslandId = B2_NULL_INDEX;\n taskContext.splitSleepTime = 0.0;\n }\n\n\n // Finalize bodies. Must happen after the constraint solver and after island splitting.\n b2FinalizeBodiesTask(0, awakeBodyCount, 0, stepContext);\n\n b2FreeStackItem(world.stackAllocator, graphBlocks);\n b2FreeStackItem(world.stackAllocator, jointBlocks);\n b2FreeStackItem(world.stackAllocator, contactBlocks);\n b2FreeStackItem(world.stackAllocator, bodyBlocks);\n\n // b2FreeStackItem(world.stackAllocator, stages);\n b2FreeStackItem(world.stackAllocator, overflowContactConstraints);\n\n // b2FreeStackItem(world.stackAllocator, joints);\n // b2FreeStackItem(world.stackAllocator, contacts);\n }\n\n // Report hit events\n // todo perhaps optimize this with a bitset\n {\n console.assert(world.contactHitArray.length === 0);\n\n const threshold = world.hitEventThreshold;\n const colors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = colors[i];\n const contactCount = color.contacts.count;\n const contactSims = color.contacts.data;\n\n for (let j = 0; j < contactCount; ++j)\n {\n const contactSim = contactSims[j];\n\n if ((contactSim.simFlags & b2ContactSimFlags.b2_simEnableHitEvent) === 0)\n {\n continue;\n }\n\n const event = new b2ContactHitEvent();\n event.approachSpeed = threshold;\n event.shapeIdA = new b2ShapeId(0, 0, 0);\n event.shapeIdB = new b2ShapeId(0, 0, 0);\n\n let hit = false;\n const pointCount = contactSim.manifold.pointCount;\n\n for (let k = 0; k < pointCount; ++k)\n {\n const mp = contactSim.manifold.points[k];\n const approachSpeed = -mp.normalVelocity;\n\n // Need to check max impulse because the point may be speculative and not colliding\n if (approachSpeed > event.approachSpeed && mp.maxNormalImpulse > 0.0)\n {\n event.approachSpeed = approachSpeed;\n event.pointX = mp.pointX;\n event.pointY = mp.pointY;\n hit = true;\n }\n }\n\n if (hit === true)\n {\n event.normalX = contactSim.manifold.normalX;\n event.normalY = contactSim.manifold.normalY;\n\n // b2CheckId(world.shapeArray, contactSim.shapeIdA);\n // b2CheckId(world.shapeArray, contactSim.shapeIdB);\n const shapeA = world.shapeArray[contactSim.shapeIdA];\n const shapeB = world.shapeArray[contactSim.shapeIdB];\n\n event.shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n event.shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n world.contactHitArray.push(event);\n }\n }\n }\n }\n\n // Gather bits for all sim bodies that have enlarged AABBs\n const simBitSet = world.taskContextArray[0].enlargedSimBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(simBitSet, world.taskContextArray[i].enlargedSimBitSet);\n }\n\n // Enlarge broad-phase proxies and build move array\n // Apply shape AABB changes to broad-phase. This also creates the move array which must be\n // in deterministic order. I'm tracking sim bodies because the number of shape ids can be huge.\n {\n const broadPhase = world.broadPhase;\n const shapes = world.shapeArray;\n const wordCount = simBitSet.blockCount;\n const bits = simBitSet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0n)\n {\n const ctz = b2CTZ64(word); // 0..63\n const bodySimIndex = 64 * k + ctz;\n\n // cache misses\n console.assert(bodySimIndex < awakeSet.sims.count);\n const bodySim = awakeSet.sims.data[bodySimIndex];\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n // b2CheckId(shapes, shapeId);\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB)\n {\n console.assert(shape.isFast === false);\n\n b2BroadPhase_EnlargeProxy(broadPhase, shape.proxyKey, shape.fatAABB);\n shape.enlargedAABB = false;\n }\n else if (shape.isFast)\n {\n // Shape is fast. It's aabb will be enlarged in continuous collision.\n b2BufferMove(broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n\n // Clear the smallest set bit\n word = word & (word - 1n);\n }\n }\n }\n\n // Continuous collision\n if (stepContext.fastBodyCount > 0)\n {\n // fast bodies\n b2FastBodyTask(0, stepContext.fastBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for fast shapes\n // Doing this here so that bullet shapes see them\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const fastBodies = stepContext.fastBodies;\n const fastBodyCount = stepContext.fastBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < fastBodyCount; ++i)\n {\n console.assert(0 <= fastBodies[i] && fastBodies[i] < awakeSet.sims.count);\n const fastBodySim = awakeSet.sims.data[fastBodies[i]];\n\n if (fastBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n fastBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, fastBodySim.bodyId);\n const fastBody = bodies[fastBodySim.bodyId];\n\n let shapeId = fastBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n\n if (stepContext.bulletBodyCount > 0)\n {\n // bullet bodies\n b2BulletBodyTask(0, stepContext.bulletBodyCount, stepContext);\n }\n\n // Serially enlarge broad-phase proxies for bullet shapes\n {\n const broadPhase = world.broadPhase;\n const dynamicTree = broadPhase.trees[b2BodyType.b2_dynamicBody];\n const bodies = world.bodyArray;\n const shapes = world.shapeArray;\n\n const bulletBodies = stepContext.bulletBodies;\n const bulletBodyCount = stepContext.bulletBodyCount;\n\n // This loop has non-deterministic order but it shouldn't affect the result\n for (let i = 0; i < bulletBodyCount; ++i)\n {\n console.assert(0 <= bulletBodies[i] && bulletBodies[i] < awakeSet.sims.count);\n const bulletBodySim = awakeSet.sims.data[bulletBodies[i]];\n\n if (bulletBodySim.enlargeAABB === false)\n {\n continue;\n }\n\n // clear flag\n bulletBodySim.enlargeAABB = false;\n\n // b2CheckIndex(bodies, bulletBodySim.bodyId);\n const bulletBody = bodies[bulletBodySim.bodyId];\n\n let shapeId = bulletBody.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = shapes[shapeId];\n\n if (shape.enlargedAABB === false)\n {\n shapeId = shape.nextShapeId;\n\n continue;\n }\n\n // clear flag\n shape.enlargedAABB = false;\n\n const proxyKey = shape.proxyKey;\n const proxyId = B2_PROXY_ID(proxyKey);\n console.assert(B2_PROXY_TYPE(proxyKey) === b2BodyType.b2_dynamicBody);\n\n // all fast shapes should already be in the move buffer\n // console.assert(b2ContainsKey(broadPhase.moveSet, proxyKey + 1));\n\n b2DynamicTree_EnlargeProxy(dynamicTree, proxyId, shape.fatAABB);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n\n b2FreeStackItem(world.stackAllocator, stepContext.bulletBodies);\n stepContext.bulletBodies = null;\n stepContext.bulletBodyCount = 0;\n\n b2FreeStackItem(world.stackAllocator, stepContext.fastBodies);\n stepContext.fastBodies = null;\n stepContext.fastBodyCount = 0;\n\n // Island sleeping\n // This must be done last because putting islands to sleep invalidates the enlarged body bits.\n if (world.enableSleep === true)\n {\n\n // Collect split island candidate for the next time step. No need to split if sleeping is disabled.\n console.assert(world.splitIslandId === B2_NULL_INDEX);\n let splitSleepTimer = 0.0;\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const taskContext = world.taskContextArray[i];\n\n if (taskContext.splitIslandId !== B2_NULL_INDEX && taskContext.splitSleepTime > splitSleepTimer)\n {\n world.splitIslandId = taskContext.splitIslandId;\n splitSleepTimer = taskContext.splitSleepTime;\n }\n }\n\n const awakeIslandBitSet = world.taskContextArray[0].awakeIslandBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n bitset_h.b2InPlaceUnion(awakeIslandBitSet, world.taskContextArray[i].awakeIslandBitSet);\n }\n\n // Need to process in reverse because this moves islands to sleeping solver sets.\n const islands = awakeSet.islands.data;\n const count = awakeSet.islands.count;\n\n for (let islandIndex = count - 1; islandIndex >= 0; islandIndex -= 1)\n {\n if (bitset_h.b2GetBit(awakeIslandBitSet, islandIndex) === true)\n {\n // this island is still awake\n continue;\n }\n\n const island = islands[islandIndex];\n const islandId = island.islandId;\n\n // console.warn(\"move island \" + islandIndex + \" \" + island.islandId + \" to sleeping solver set\");\n\n b2TrySleepIsland(world, islandId);\n }\n\n b2ValidateSolverSets(world);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_lengthUnitsPerMeter, b2_linearSlop } from './include/core_h.js';\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2Dot,\n b2Length,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RightPerp,\n b2RotateVector,\n b2Sub,\n b2TransformPoint\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace DistanceJoint\n */\n\n/**\n * @function b2DistanceJoint_SetLength\n * @summary Sets the target length of a distance joint and resets its impulses.\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {number} length - The desired length of the joint, clamped between b2_linearSlop and B2_HUGE.\n * @returns {void}\n * @description\n * Sets the target length of a distance joint. The length value is automatically\n * clamped between b2_linearSlop and B2_HUGE. After setting the length,\n * the joint's impulse values are reset to zero.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_SetLength(jointId, length)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n joint.length = b2ClampFloat(length, b2_linearSlop, B2_HUGE);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * @summary Gets the length of a distance joint.\n * @function b2DistanceJoint_GetLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current length of the distance joint.\n * @description\n * Returns the current length of a distance joint. The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.length;\n}\n\n/**\n * @summary Enables or disables the limit constraint on a distance joint.\n * @function b2DistanceJoint_EnableLimit\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {boolean} enableLimit - True to enable the joint's limit, false to disable it.\n * @returns {void}\n * @description\n * Sets the enable/disable state of the limit constraint for a distance joint.\n * The joint must be of type b2_distanceJoint or an error will occur.\n * @throws {Error} Throws an error if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableLimit(jointId, enableLimit)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n joint.enableLimit = enableLimit;\n}\n\n/**\n * @summary Checks if the limit is enabled for a distance joint.\n * @function b2DistanceJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableLimit;\n}\n\n/**\n * @function b2DistanceJoint_SetLengthRange\n * @description\n * Sets the minimum and maximum length constraints for a distance joint.\n * The values are clamped between b2_linearSlop and B2_HUGE.\n * The function resets all impulse values to zero after updating the length range.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {number} minLength - The minimum allowed length of the joint\n * @param {number} maxLength - The maximum allowed length of the joint\n * @returns {void}\n * @throws {Error} If the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetLengthRange(jointId, minLength, maxLength)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n minLength = b2ClampFloat(minLength, b2_linearSlop, B2_HUGE);\n maxLength = b2ClampFloat(maxLength, b2_linearSlop, B2_HUGE);\n joint.minLength = Math.min(minLength, maxLength);\n joint.maxLength = Math.max(minLength, maxLength);\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n}\n\n/**\n * Gets the minimum length of a distance joint.\n * @function b2DistanceJoint_GetMinLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The minimum length value of the distance joint.\n * @throws {Error} If the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMinLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.minLength;\n}\n\n/**\n * Gets the maximum length of a distance joint.\n * @function b2DistanceJoint_GetMaxLength\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum length value of the distance joint.\n * @throws {Error} If the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMaxLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.maxLength;\n}\n\n/**\n * @function b2DistanceJoint_GetCurrentLength\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @returns {number} The current length between the two anchor points of the distance joint\n * @description\n * Calculates the current distance between the two anchor points of a distance joint\n * in world coordinates. The function transforms the local anchor points of both bodies\n * to world coordinates and computes the distance between them.\n * @throws {Error} Returns 0 if the world is locked\n */\nexport function b2DistanceJoint_GetCurrentLength(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n const world = b2GetWorld(jointId.world0);\n\n if (world.locked)\n {\n return 0.0;\n }\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const length = b2Length(d);\n\n return length;\n}\n\n/**\n * @summary Enables or disables the spring behavior of a distance joint.\n * @function b2DistanceJoint_EnableSpring\n * @param {b2JointId} jointId - The identifier of the distance joint to modify.\n * @param {boolean} enableSpring - True to enable spring behavior, false to disable it.\n * @returns {void}\n * @description\n * Sets the spring behavior state of a distance joint. When enabled, the joint acts like\n * a spring between two bodies. When disabled, the joint maintains a fixed distance\n * between the connected bodies.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_EnableSpring(jointId, enableSpring)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.enableSpring = enableSpring;\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a distance joint.\n * @function b2DistanceJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @description\n * Returns the state of the spring enable flag for the specified distance joint.\n * The function validates that the joint is of type b2_distanceJoint before\n * accessing the spring enable property.\n * @throws {Error} Throws an error if the joint is not of type b2_distanceJoint.\n */\nexport function b2DistanceJoint_IsSpringEnabled(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return base.distanceJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (hertz) of a distance joint.\n * @function b2DistanceJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (oscillations per second).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a distance joint. The frequency\n * determines how quickly the spring oscillates when disturbed from equilibrium.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_SetSpringHertz(jointId, hertz)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.hertz = hertz;\n}\n\n/**\n * Sets the damping ratio for a distance joint's spring.\n * @function b2DistanceJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the distance joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @description\n * Sets the damping ratio parameter for a distance joint's spring mechanism.\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint\n */\nexport function b2DistanceJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n base.distanceJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the hertz frequency parameter of a distance joint.\n * @function b2DistanceJoint_GetSpringHertz\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The hertz frequency value of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.hertz;\n}\n\n/**\n * Gets the damping ratio of a distance joint.\n * @function b2DistanceJoint_GetSpringDampingRatio\n * @param {number} jointId - The identifier for the distance joint.\n * @returns {number} The damping ratio of the distance joint.\n * @throws {Error} If the joint is not a distance joint or the jointId is invalid.\n */\nexport function b2DistanceJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n const joint = base.distanceJoint;\n\n return joint.dampingRatio;\n}\n\n/**\n * @function b2DistanceJoint_EnableMotor\n * @description\n * Enables or disables the motor on a distance joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the distance joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a distance joint type\n */\nexport function b2DistanceJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n if (enableMotor !== joint.distanceJoint.enableMotor)\n {\n joint.distanceJoint.enableMotor = enableMotor;\n joint.distanceJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a distance joint.\n * @function b2DistanceJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the distance joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not a distance joint.\n */\nexport function b2DistanceJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.enableMotor;\n}\n\n/**\n * Sets the motor speed for a distance joint.\n * @function b2DistanceJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} motorSpeed - The new motor speed value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a distance joint.\n * @function b2DistanceJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor speed of the distance joint in radians per second.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.motorSpeed;\n}\n\n/**\n * Gets the current motor force for a distance joint.\n * @function b2DistanceJoint_GetMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The current motor force in Newtons, calculated as the motor impulse divided by the step time.\n * @description\n * Calculates the motor force by dividing the joint's motor impulse by the inverse time step (inv_h).\n * The joint must be of type b2_distanceJoint.\n * @throws {Error} Throws if the joint type is not b2_distanceJoint.\n */\nexport function b2DistanceJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return world.inv_h * base.distanceJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a distance joint.\n * @function b2DistanceJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint to modify.\n * @param {number} force - The maximum force the motor can generate.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a distance joint type.\n */\nexport function b2DistanceJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n joint.distanceJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a distance joint.\n * @function b2DistanceJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the distance joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not a distance joint or the joint ID is invalid.\n */\nexport function b2DistanceJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_distanceJoint);\n\n return joint.distanceJoint.maxMotorForce;\n}\n\nexport function b2GetDistanceJointForce(world, base)\n{\n const joint = base.distanceJoint;\n\n const transformA = b2GetBodyTransform(world, base.bodyIdA);\n const transformB = b2GetBodyTransform(world, base.bodyIdB);\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const d = b2Sub(pB, pA);\n const axis = b2Normalize(d);\n const force = (joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse) * world.inv_h;\n\n return b2MulSV(force, axis);\n}\n\nexport function b2PrepareDistanceJoint(base, context)\n{\n const world = context.world;\n const bodies = world.bodyArray;\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.distanceJoint;\n\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const separation = b2Add(b2Sub(rB, rA), joint.deltaCenter);\n const axis = b2Normalize(separation);\n\n const crA = b2Cross(rA, axis);\n const crB = b2Cross(rB, axis);\n const k = mA + mB + iA * crA * crA + iB * crB * crB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.distanceSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.impulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n joint.motorImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartDistanceJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n const axis = b2Normalize(separation);\n\n const axialImpulse = joint.impulse + joint.lowerImpulse - joint.upperImpulse + joint.motorImpulse;\n const P = b2MulSV(axialImpulse, axis);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * b2Cross(rA, P);\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * b2Cross(rB, P);\n}\n\nexport function b2SolveDistanceJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.distanceJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const ds = b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), b2Sub(rB, rA));\n const separation = b2Add(joint.deltaCenter, ds);\n\n const length = b2Length(separation);\n const axis = b2Normalize(separation);\n\n if (joint.enableSpring && (joint.minLength < joint.maxLength || joint.enableLimit === false))\n {\n if (joint.hertz > 0.0)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const C = length - joint.length;\n const bias = joint.distanceSoftness.biasRate * C;\n\n const m = joint.distanceSoftness.massScale * joint.axialMass;\n const impulse = -m * (Cdot + bias) - joint.distanceSoftness.impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n if (joint.enableLimit)\n {\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.minLength;\n\n let bias = 0.0;\n let massCoeff = 1.0;\n let impulseCoeff = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massCoeff = context.jointSoftness.massScale;\n impulseCoeff = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massCoeff * joint.axialMass * (Cdot + bias) - impulseCoeff * joint.lowerImpulse;\n const newImpulse = Math.max(0.0, joint.lowerImpulse + impulse);\n const deltaImpulse = newImpulse - joint.lowerImpulse;\n joint.lowerImpulse = newImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n {\n const vr = b2Add(b2Sub(vA, vB), b2Sub(b2CrossSV(wA, rA), b2CrossSV(wB, rB)));\n const Cdot = b2Dot(axis, vr);\n\n const C = joint.maxLength - length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const newImpulse = Math.max(0.0, joint.upperImpulse + impulse);\n const deltaImpulse = newImpulse - joint.upperImpulse;\n joint.upperImpulse = newImpulse;\n\n const P = b2MulSV(-deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n\n if (joint.enableMotor)\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n const impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n const deltaImpulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(deltaImpulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n }\n else\n {\n const vr = b2Add(b2Sub(vB, vA), b2Sub(b2CrossSV(wB, rB), b2CrossSV(wA, rA)));\n const Cdot = b2Dot(axis, vr);\n\n const C = length - joint.length;\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.impulse;\n joint.impulse += impulse;\n\n const P = b2MulSV(impulse, axis);\n vA = b2MulSub(vA, mA, P);\n wA -= iA * b2Cross(rA, P);\n vB = b2MulAdd(vB, mB, P);\n wB += iB * b2Cross(rB, P);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawDistanceJoint(draw, base, transformA, transformB)\n{\n const joint = base.distanceJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const axis = b2Normalize(b2Sub(pB, pA));\n\n if (joint.minLength < joint.maxLength && joint.enableLimit)\n {\n const pMin = b2MulAdd(pA, joint.minLength, axis);\n const pMax = b2MulAdd(pA, joint.maxLength, axis);\n const offset = b2MulSV(0.05 * b2_lengthUnitsPerMeter, b2RightPerp(axis));\n\n if (joint.minLength > b2_linearSlop)\n {\n draw.DrawSegment(b2Sub(pMin, offset), b2Add(pMin, offset), b2HexColor.b2_colorLightGreen, draw.context);\n }\n\n if (joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(b2Sub(pMax, offset), b2Add(pMax, offset), b2HexColor.b2_colorRed, draw.context);\n }\n\n if (joint.minLength > b2_linearSlop && joint.maxLength < B2_HUGE)\n {\n draw.DrawSegment(pMin, pMax, b2HexColor.b2_colorGray, draw.context);\n }\n }\n\n draw.DrawSegment(pA, pB, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pA.x, pA.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, b2HexColor.b2_colorWhite, draw.context);\n\n if (joint.hertz > 0.0 && joint.enableSpring)\n {\n const pRest = b2MulAdd(pA, joint.length, axis);\n draw.DrawPoint(pRest.x, pRest.y, 4.0, b2HexColor.b2_colorBlue, draw.context);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2Dot,\n b2LeftPerp,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace PrismaticJoint\n */\n\n/**\n * @function b2PrismaticJoint_EnableSpring\n * @summary Enables or disables the spring functionality of a prismatic joint.\n * @param {b2JointId} jointId - The identifier of the prismatic joint to modify.\n * @param {boolean} enableSpring - Whether to enable (true) or disable (false) the spring.\n * @returns {void}\n * @description\n * Sets the spring state of a prismatic joint. When the spring state changes,\n * the spring impulse is reset to zero. If the state doesn't change, no action is taken.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableSpring !== joint.prismaticJoint.enableSpring)\n {\n joint.prismaticJoint.enableSpring = enableSpring;\n joint.prismaticJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the spring mechanism is enabled, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a prismatic joint.\n * @function b2PrismaticJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} hertz - The spring frequency in Hertz.\n * @returns {void}\n * @description\n * Updates the spring frequency of a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a prismatic joint.\n * @function b2PrismaticJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.hertz;\n}\n\n/**\n * @summary Sets the damping ratio for a prismatic joint's spring.\n * @function b2PrismaticJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @description\n * Sets the spring damping ratio for a prismatic joint. The joint must be of type b2_prismaticJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a prismatic joint.\n * @function b2PrismaticJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.dampingRatio;\n}\n\n/**\n * @function b2PrismaticJoint_EnableLimit\n * @description\n * Enables or disables the translation limits on a prismatic joint. When the limit is disabled,\n * the joint's limit impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a prismatic joint\n */\nexport function b2PrismaticJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableLimit !== joint.prismaticJoint.enableLimit)\n {\n joint.prismaticJoint.enableLimit = enableLimit;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a prismatic joint.\n * @function b2PrismaticJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the limit is enabled for the joint, false otherwise.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableLimit;\n}\n\n/**\n * @summary Gets the lower translation limit of a prismatic joint.\n * @function b2PrismaticJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The lower translation limit of the prismatic joint.\n * @throws {Error} Throws an error if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.lowerTranslation;\n}\n\n/**\n * @function b2PrismaticJoint_GetUpperLimit\n * @summary Gets the upper translation limit of a prismatic joint.\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The upper translation limit of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.upperTranslation;\n}\n\n/**\n * Sets the translation limits for a prismatic joint.\n * @function b2PrismaticJoint_SetLimits\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a prismatic joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to\n * the upper value. When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (lower !== joint.prismaticJoint.lowerTranslation || upper !== joint.prismaticJoint.upperTranslation)\n {\n joint.prismaticJoint.lowerTranslation = Math.min(lower, upper);\n joint.prismaticJoint.upperTranslation = Math.max(lower, upper);\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2PrismaticJoint_EnableMotor\n * @description\n * Enables or disables the motor on a prismatic joint. When the motor is disabled,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the prismatic joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_prismaticJoint\n */\nexport function b2PrismaticJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n if (enableMotor !== joint.prismaticJoint.enableMotor)\n {\n joint.prismaticJoint.enableMotor = enableMotor;\n joint.prismaticJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a prismatic joint.\n * @function b2PrismaticJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the prismatic joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a prismatic joint.\n * @function b2PrismaticJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a prismatic joint.\n * @function b2PrismaticJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The current motor speed of the prismatic joint.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.motorSpeed;\n}\n\n/**\n * @function b2PrismaticJoint_GetMotorForce\n * @param {b2JointId} jointId - The ID of the prismatic joint\n * @returns {number} The current motor force in Newtons\n * @description\n * Gets the current motor force of a prismatic joint. The force is calculated by\n * multiplying the joint's motor impulse by the inverse of the world's time step.\n * @throws {Error} Throws if the joint type is not a prismatic joint\n */\nexport function b2PrismaticJoint_GetMotorForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return world.inv_h * base.prismaticJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor force for a prismatic joint.\n * @function b2PrismaticJoint_SetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @param {number} force - The maximum force the motor can apply.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_SetMaxMotorForce(jointId, force)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n joint.prismaticJoint.maxMotorForce = force;\n}\n\n/**\n * Gets the maximum motor force of a prismatic joint.\n * @function b2PrismaticJoint_GetMaxMotorForce\n * @param {b2JointId} jointId - The identifier for the prismatic joint.\n * @returns {number} The maximum force that can be applied by the joint's motor.\n * @throws {Error} If the joint is not of type b2_prismaticJoint.\n */\nexport function b2PrismaticJoint_GetMaxMotorForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_prismaticJoint);\n\n return joint.prismaticJoint.maxMotorForce;\n}\n\nexport function b2GetPrismaticJointForce(world, base)\n{\n const idA = base.bodyIdA;\n const transformA = b2GetBodyTransform(world, idA);\n\n const joint = base.prismaticJoint;\n\n const axisA = b2RotateVector(transformA.q, joint.localAxisA);\n const perpA = b2LeftPerp(axisA);\n\n const inv_h = world.inv_h;\n const perpForce = inv_h * joint.impulse.x;\n const axialForce = inv_h * (joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetPrismaticJointTorque(world, base)\n{\n return world.inv_h * base.prismaticJoint.impulse.y;\n}\n\n// Linear constraint (point-to-line)\n// d = p2 - p1 = x2 + r2 - x1 - r1\n// C = dot(perp, d)\n// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))\n// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)\n// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]\n//\n// Angular constraint\n// C = a2 - a1 + a_initial\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n//\n// K = J * invM * JT\n//\n// J = [-a -s1 a s2]\n// [0 -1 0 1]\n// a = perp\n// s1 = cross(d + r1, a) = cross(p2 - x1, a)\n// s2 = cross(r2, a) = cross(p2 - x2, a)\n\n// Motor/Limit linear constraint\n// C = dot(ax1, d)\n// Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)\n// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]\n\n// Predictive limit is applied even when the limit is not active.\n// Prevents a constraint speed that can lead to a constraint error in one time step.\n// Want C2 = C1 + h * Cdot >= 0\n// Or:\n// Cdot + C1/h >= 0\n// I do not apply a negative constraint error because that is handled in position correction.\n// So:\n// Cdot + max(C1, 0)/h >= 0\n\n// Block Solver\n// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer.\n//\n// The Jacobian has 2 rows:\n// J = [-uT -s1 uT s2] // linear\n// [0 -1 0 1] // angular\n//\n// u = perp\n// s1 = cross(d + r1, u), s2 = cross(r2, u)\n// a1 = cross(d + r1, v), a2 = cross(r2, v)\n\nexport function b2PreparePrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // Comment out b2CheckIndex\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n // Comment out B2_ASSERT\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n // Comment out B2_ASSERT\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.prismaticJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const a1 = b2Cross(b2Add(d, rA), joint.axisA);\n const a2 = b2Cross(rB, joint.axisA);\n\n // effective masses\n const k = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting == false)\n {\n joint.impulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartPrismaticJoint(base, context)\n{\n // Comment out B2_ASSERT\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n\n // impulse is applied at anchor point on body B\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n // perpendicular constraint\n const perpA = b2LeftPerp(axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const perpImpulse = joint.impulse.x;\n const angleImpulse = joint.impulse.y;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(perpImpulse, perpA));\n const LA = axialImpulse * a1 + perpImpulse * s1 + angleImpulse;\n const LB = axialImpulse * a2 + perpImpulse * s2 + angleImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolvePrismaticJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.prismaticJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n // These scalars are for torques generated by axial forces\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Solve motor constraint\n if (joint.enableMotor)\n {\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = joint.axialMass * (joint.motorSpeed - Cdot);\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorForce;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.lowerImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const oldImpulse = joint.upperImpulse;\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -joint.axialMass * massScale * (Cdot + bias) - impulseScale * oldImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // Solve the prismatic constraint in block form\n {\n const perpA = b2LeftPerp(axisA);\n\n // These scalars are for torques generated by the perpendicular constraint force\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const Cdot = new b2Vec2(b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA, wB - wA);\n\n let bias = new b2Vec2();\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = new b2Vec2(b2Dot(perpA, d), b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle);\n bias = b2MulSV(context.jointSoftness.biasRate, C);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n const k12 = iA * s1 + iB * s2;\n let k22 = iA + iB;\n\n if (k22 === 0.0)\n {\n // For bodies with fixed rotation.\n k22 = 1.0;\n }\n\n const K = new b2Mat22(new b2Vec2(k11, k12), new b2Vec2(k12, k22));\n\n const b = b2Solve22(K, b2Add(Cdot, bias));\n const impulse = new b2Vec2(-massScale * b.x - impulseScale * joint.impulse.x, -massScale * b.y - impulseScale * joint.impulse.y);\n joint.impulse.x += impulse.x;\n joint.impulse.y += impulse.y;\n\n const P = b2MulSV(impulse.x, perpA);\n const LA = impulse.x * s1 + impulse.y;\n const LB = impulse.x * s2 + impulse.y;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2DrawPrismaticJoint(draw, base, transformA, transformB)\n{\n console.assert(base.type == b2JointType.b2_prismaticJoint);\n const joint = base.prismaticJoint;\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorBlue;\n const c5 = b2HexColor.b2_colorGray4;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2TransformPoint,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\nimport { b2BodyState, b2GetBodyTransform } from './include/body_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2GetJointSimCheckType } from './joint_c.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace RevoluteJoint\n */\n\n/**\n * @function b2RevoluteJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a revolute joint.\n * When the spring state changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier of the revolute joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableSpring !== joint.revoluteJoint.enableSpring)\n {\n joint.revoluteJoint.enableSpring = enableSpring;\n joint.revoluteJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if spring functionality is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if spring functionality is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a revolute joint.\n * @function b2RevoluteJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring oscillation frequency for a revolute joint. The joint must be\n * of type b2_revoluteJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a revolute joint.\n * @function b2RevoluteJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a revolute joint's spring.\n * @function b2RevoluteJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} dampingRatio - The damping ratio for the spring.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a revolute joint.\n * @function b2RevoluteJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The spring damping ratio value of the revolute joint.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.dampingRatio;\n}\n\n/**\n * @function b2RevoluteJoint_GetAngle\n * @summary Gets the current angle between two bodies connected by a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current angle in radians between the two connected bodies,\n * relative to the reference angle.\n * @description\n * Calculates the relative angle between two bodies connected by a revolute joint by\n * comparing their transforms and subtracting the joint's reference angle. The result\n * is unwound to ensure consistent angle representation.\n */\nexport function b2RevoluteJoint_GetAngle(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const jointSim = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n const transformA = b2GetBodyTransform(world, jointSim.bodyIdA);\n const transformB = b2GetBodyTransform(world, jointSim.bodyIdB);\n\n let angle = b2RelativeAngle(transformB.q, transformA.q) - jointSim.revoluteJoint.referenceAngle;\n angle = b2UnwindAngle(angle);\n\n return angle;\n}\n\n/**\n * @function b2RevoluteJoint_EnableLimit\n * @summary Enables or disables the joint angle limits for a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {boolean} enableLimit - True to enable the joint limits, false to disable them.\n * @returns {void}\n * @description\n * When enabled, the joint will restrict rotation to be between its upper and lower angle limits.\n * When the limit state changes, the joint's limit impulses are reset to zero.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableLimit !== joint.revoluteJoint.enableLimit)\n {\n joint.revoluteJoint.enableLimit = enableLimit;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a revolute joint.\n * @function b2RevoluteJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the joint's limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableLimit;\n}\n\n/**\n * Gets the lower angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The lower angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.lowerAngle;\n}\n\n/**\n * Gets the upper angle limit of a revolute joint.\n * @function b2RevoluteJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The upper angle limit in radians.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.upperAngle;\n}\n\n/**\n * @function b2RevoluteJoint_SetLimits\n * @description\n * Sets the lower and upper angle limits for a revolute joint. The function automatically\n * orders the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint impulses are reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint to modify\n * @param {number} lower - The lower angle limit in radians\n * @param {number} upper - The upper angle limit in radians\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (lower !== joint.revoluteJoint.lowerAngle || upper !== joint.revoluteJoint.upperAngle)\n {\n joint.revoluteJoint.lowerAngle = Math.min(lower, upper);\n joint.revoluteJoint.upperAngle = Math.max(lower, upper);\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2RevoluteJoint_EnableMotor\n * @description\n * Enables or disables the motor on a revolute joint. When the motor is disabled,\n * its accumulated impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the revolute joint\n * @param {boolean} enableMotor - True to enable the joint's motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_revoluteJoint\n */\nexport function b2RevoluteJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n if (enableMotor !== joint.revoluteJoint.enableMotor)\n {\n joint.revoluteJoint.enableMotor = enableMotor;\n joint.revoluteJoint.motorImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a revolute joint.\n * @function b2RevoluteJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the revolute joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a revolute joint.\n * @function b2RevoluteJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @description\n * Sets the angular velocity for the motor of a revolute joint. A positive velocity\n * means the joint will rotate counterclockwise.\n * @throws {Error} Throws an error if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a revolute joint.\n * @function b2RevoluteJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier of the revolute joint.\n * @returns {number} The current motor speed in radians per second.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.motorSpeed;\n}\n\n/**\n * @function b2RevoluteJoint_GetMotorTorque\n * @summary Gets the current motor torque of a revolute joint.\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The current motor torque in Newton-meters.\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_revoluteJoint.\n * @throws {Error} If the joint type is not b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return world.inv_h * joint.revoluteJoint.motorImpulse;\n}\n\n/**\n * Sets the maximum motor torque for a revolute joint.\n * @function b2RevoluteJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n joint.revoluteJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a revolute joint.\n * @function b2RevoluteJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the revolute joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not of type b2_revoluteJoint.\n */\nexport function b2RevoluteJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_revoluteJoint);\n\n return joint.revoluteJoint.maxMotorTorque;\n}\n\nexport function b2GetRevoluteJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.revoluteJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetRevoluteJointTorque(world, base)\n{\n const revolute = base.revoluteJoint;\n const torque = world.inv_h * (revolute.motorImpulse + revolute.lowerImpulse - revolute.upperImpulse);\n\n return torque;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n\n// Motor constraint\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\n// Body State\n// The solver operates on the body state. The body state array does not hold static bodies. Static bodies are shared\n// across worker threads. It would be okay to read their states, but writing to them would cause cache thrashing across\n// workers, even if the values don't change.\n// This causes some trouble when computing anchors. I rotate the anchors using the body rotation every sub-step. For static\n// bodies the anchor doesn't rotate. Body A or B could be static and this can lead to lots of branching. This branching\n// should be minimized.\n//\n// Solution 1:\n// Use delta rotations. This means anchors need to be prepared in world space. The delta rotation for static bodies will be\n// identity. Base separation and angles need to be computed. Manifolds will be behind a frame, but that is probably best if bodies\n// move fast.\n//\n// Solution 2:\n// Use full rotation. The anchors for static bodies will be in world space while the anchors for dynamic bodies will be in local\n// space. Potentially confusing and bug prone.\n\nexport function b2PrepareRevoluteJoint(base, context)\n{\n // chase body id to the solver set where the body lives\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert( bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet, `bodyA.setIndex = ${bodyA.setIndex}, bodyB.setIndex = ${bodyB.setIndex}` );\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert( 0 <= localIndexA && localIndexA <= setA.sims.count );\n console.assert( 0 <= localIndexB && localIndexB <= setB.sims.count );\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.revoluteJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n // initial anchors in world space\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.referenceAngle;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle); // yes, this does seem to be deliberate reuse (line 254: revolute_joint.c)\n\n const k = iA + iB;\n joint.axialMass = k > 0.0 ? 1.0 / k : 0.0;\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartRevoluteJoint(base, context)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.revoluteJoint;\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const axialImpulse = joint.springImpulse + joint.motorImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + axialImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + axialImpulse);\n}\n\nexport function b2SolveRevoluteJoint(base, context, useBias)\n{\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.revoluteJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity.clone();\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // const float maxBias = context.maxBiasVelocity;\n\n // Solve spring.\n if (joint.enableSpring && fixedRotation === false)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Solve motor constraint.\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.axialMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n if (joint.enableLimit && fixedRotation === false)\n {\n let jointAngle = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n jointAngle = b2UnwindAngle(jointAngle);\n\n // Lower limit\n {\n const C = jointAngle - joint.lowerAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(joint.lowerImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // Upper limit\n // Note: signs are flipped to keep C positive when the constraint is satisfied.\n // This also keeps the impulse positive when the limit is active.\n {\n const C = joint.upperAngle - jointAngle;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n // sign flipped on Cdot\n const Cdot = wA - wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(joint.upperImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n // sign flipped on applied impulse\n wA += iA * impulse;\n wB -= iB * impulse;\n }\n }\n\n // Solve point-to-point constraint\n {\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n\n const separation = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n bias = b2MulSV(context.jointSoftness.biasRate, separation);\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y\n );\n joint.linearImpulse.x += impulse.x;\n joint.linearImpulse.y += impulse.y;\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C original function\n\nvoid b2RevoluteJoint::Dump()\n{\n int32 indexA = joint.bodyA.joint.islandIndex;\n int32 indexB = joint.bodyB.joint.islandIndex;\n\n b2Dump(\" b2RevoluteJointDef jd;\\n\");\n b2Dump(\" jd.bodyA = bodies[%d];\\n\", indexA);\n b2Dump(\" jd.bodyB = bodies[%d];\\n\", indexB);\n b2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n b2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n b2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n b2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n b2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n b2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n b2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n b2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n b2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n b2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n b2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.,,index);\n}\n * @memberof RevoluteJoint\n */\nexport function b2DrawRevoluteJoint(draw, base, transformA, transformB, drawSize)\n{\n\n console.assert( base.type == b2JointType.b2_revoluteJoint );\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n\n const c1 = b2HexColor.b2_colorRed;\n\n // let c2 = b2HexColor.b2_colorGreen;\n // let c3 = b2HexColor.b2_colorRed;\n\n const L = drawSize;\n draw.DrawCircle(pB, L, c1, draw.context);\n\n const angle = b2RelativeAngle(transformB.q, transformA.q);\n\n const r = new b2Vec2(L * Math.cos(angle), L * Math.sin(angle));\n\n const pC = b2Add(pB, r);\n draw.DrawSegment(pB, pC, c1, draw.context);\n\n // if (draw.drawJointExtras) {\n // let jointAngle = b2UnwindAngle(angle - joint.referenceAngle);\n // let buffer = ` ${(180.0 * jointAngle / Math.PI).toFixed(1)} deg`;\n // draw.DrawString(pC, buffer, draw.context);\n // }\n\n // let lowerAngle = joint.lowerAngle + joint.referenceAngle;\n // let upperAngle = joint.upperAngle + joint.referenceAngle;\n\n // if (joint.enableLimit) {\n // const rlo = new b2Vec2(L * Math.cos(lowerAngle), L * Math.sin(lowerAngle));\n // const rhi = new b2Vec2(L * Math.cos(upperAngle), L * Math.sin(upperAngle));\n\n\n // draw.DrawSegment(pB, b2Add(pB, rlo), c2, draw.context);\n // draw.DrawSegment(pB, b2Add(pB, rhi), c3, draw.context);\n\n // const ref = new b2Vec2(L * Math.cos(joint.referenceAngle), L * Math.sin(joint.referenceAngle));\n\n // draw.DrawSegment(pB, b2Add(pB, ref), b2HexColor.b2_colorBlue, draw.context);\n // }\n\n const color = b2HexColor.b2_colorGold;\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2ClampFloat, b2Cross, b2Dot, b2LeftPerp, b2MulAdd, b2MulSV, b2MulSub, b2RotateVector, b2Sub, b2TransformPoint } from './include/math_functions_h.js';\nimport { b2GetWorld, b2SetType } from './include/world_h.js';\nimport { b2HexColor, b2JointType } from './include/types_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\n\n/**\n * @namespace WheelJoint\n */\n\n/**\n * @function b2WheelJoint_EnableSpring\n * @description\n * Enables or disables the spring functionality of a wheel joint. When the spring state\n * changes, the spring impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {boolean} enableSpring - True to enable the spring, false to disable it\n * @returns {void}\n * @throws {Error} If the joint identified by jointId is not a wheel joint\n */\nexport function b2WheelJoint_EnableSpring(jointId, enableSpring)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (enableSpring !== joint.wheelJoint.enableSpring)\n {\n joint.wheelJoint.enableSpring = enableSpring;\n joint.wheelJoint.springImpulse = 0.0;\n }\n}\n\n/**\n * @summary Checks if the spring mechanism is enabled for a wheel joint.\n * @function b2WheelJoint_IsSpringEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the spring is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsSpringEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableSpring;\n}\n\n/**\n * @summary Sets the spring frequency for a wheel joint.\n * @function b2WheelJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @description\n * Sets the spring frequency for a wheel joint's oscillation. The frequency is specified\n * in Hertz (Hz). The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetSpringHertz(jointId, hertz)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz for a wheel joint.\n * @function b2WheelJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a wheel joint's spring.\n * @function b2WheelJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify\n * @param {number} dampingRatio - The damping ratio for the spring (0 = no damping, 1 = critical damping)\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the damping ratio of a wheel joint's spring.\n * @function b2WheelJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The spring damping ratio value.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetSpringDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.dampingRatio;\n}\n\n/**\n * @function b2WheelJoint_EnableLimit\n * @summary Enables or disables the joint's translation limit.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {boolean} enableLimit - True to enable the translation limit, false to disable it.\n * @returns {void}\n * @description\n * Sets whether the wheel joint's translation limit is active. When the limit is enabled,\n * the joint's translation will be constrained. When the limit state changes, the joint's\n * lower and upper impulses are reset to zero.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_EnableLimit(jointId, enableLimit)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableLimit !== enableLimit)\n {\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.enableLimit = enableLimit;\n }\n}\n\n/**\n * @summary Checks if the limit is enabled for a wheel joint.\n * @function b2WheelJoint_IsLimitEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the limit is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint.\n */\nexport function b2WheelJoint_IsLimitEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableLimit;\n}\n\n/**\n * Gets the lower translation limit of a wheel joint.\n * @function b2WheelJoint_GetLowerLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The lower translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the jointId is invalid.\n */\nexport function b2WheelJoint_GetLowerLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.lowerTranslation;\n}\n\n/**\n * Gets the upper translation limit of a wheel joint.\n * @function b2WheelJoint_GetUpperLimit\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The upper translation limit of the wheel joint.\n * @throws {Error} If the joint is not a wheel joint or the joint ID is invalid.\n */\nexport function b2WheelJoint_GetUpperLimit(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.upperTranslation;\n}\n\n/**\n * @function b2WheelJoint_SetLimits\n * @summary Sets the translation limits for a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} lower - The lower translation limit.\n * @param {number} upper - The upper translation limit.\n * @returns {void}\n * @description\n * Sets new translation limits for a wheel joint. The function automatically orders\n * the limits so that the lower value is always less than or equal to the upper value.\n * When the limits change, the joint's impulses are reset to zero.\n * @throws {Error} If the provided jointId does not reference a valid wheel joint.\n */\nexport function b2WheelJoint_SetLimits(jointId, lower, upper)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (lower !== joint.wheelJoint.lowerTranslation || upper !== joint.wheelJoint.upperTranslation)\n {\n joint.wheelJoint.lowerTranslation = Math.min(lower, upper);\n joint.wheelJoint.upperTranslation = Math.max(lower, upper);\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n }\n}\n\n/**\n * @function b2WheelJoint_EnableMotor\n * @description\n * Enables or disables the motor on a wheel joint. When the motor state changes,\n * the motor impulse is reset to zero.\n * @param {b2JointId} jointId - The identifier for the wheel joint\n * @param {boolean} enableMotor - True to enable the motor, false to disable it\n * @returns {void}\n * @throws {Error} If the joint is not a wheel joint type\n */\nexport function b2WheelJoint_EnableMotor(jointId, enableMotor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n if (joint.wheelJoint.enableMotor !== enableMotor)\n {\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.enableMotor = enableMotor;\n }\n}\n\n/**\n * @summary Checks if the motor is enabled on a wheel joint.\n * @function b2WheelJoint_IsMotorEnabled\n * @param {b2JointId} jointId - The identifier for the wheel joint to check.\n * @returns {boolean} True if the motor is enabled, false otherwise.\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_IsMotorEnabled(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.enableMotor;\n}\n\n/**\n * @summary Sets the motor speed for a wheel joint.\n * @function b2WheelJoint_SetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint to modify.\n * @param {number} motorSpeed - The desired motor speed in radians per second.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_SetMotorSpeed(jointId, motorSpeed)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.motorSpeed = motorSpeed;\n}\n\n/**\n * Gets the motor speed of a wheel joint.\n * @function b2WheelJoint_GetMotorSpeed\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor speed of the wheel joint in radians per second.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMotorSpeed(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.motorSpeed;\n}\n\n/**\n * @function b2WheelJoint_GetMotorTorque\n * @summary Gets the current motor torque of a wheel joint.\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The current motor torque normalized by the step time (N\u22C5m).\n * @description\n * Calculates the motor torque by multiplying the motor impulse by the inverse\n * of the time step. The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws if the joint type is not b2_wheelJoint.\n */\nexport function b2WheelJoint_GetMotorTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return world.inv_h * joint.wheelJoint.motorImpulse;\n}\n\n/**\n * @summary Sets the maximum motor torque for a wheel joint.\n * @function b2WheelJoint_SetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @param {number} torque - The maximum motor torque value to set.\n * @returns {void}\n * @description\n * Sets the maximum torque that can be applied by the wheel joint's motor.\n * The joint must be of type b2_wheelJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_wheelJoint.\n */\nexport function b2WheelJoint_SetMaxMotorTorque(jointId, torque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n joint.wheelJoint.maxMotorTorque = torque;\n}\n\n/**\n * Gets the maximum motor torque of a wheel joint.\n * @function b2WheelJoint_GetMaxMotorTorque\n * @param {b2JointId} jointId - The identifier for the wheel joint.\n * @returns {number} The maximum motor torque value.\n * @throws {Error} If the joint is not a wheel joint type.\n */\nexport function b2WheelJoint_GetMaxMotorTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_wheelJoint);\n\n return joint.wheelJoint.maxMotorTorque;\n}\n\nexport function b2GetWheelJointForce(world, base)\n{\n const joint = base.wheelJoint;\n\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const perpForce = world.inv_h * joint.perpImpulse;\n const axialForce = world.inv_h * (joint.springImpulse + joint.lowerImpulse - joint.upperImpulse);\n\n const force = b2Add(b2MulSV(perpForce, perpA), b2MulSV(axialForce, axisA));\n\n return force;\n}\n\nexport function b2GetWheelJointTorque(world, base)\n{\n return world.inv_h * base.wheelJoint.motorImpulse;\n}\n\n// Linear constraint (point-to-line)\n// d = pB - pA = xB + rB - xA - rA\n// C = dot(ay, d)\n// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA))\n// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB)\n// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)]\n\n// Spring linear constraint\n// C = dot(ax, d)\n// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB)\n// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)]\n\n// Motor rotational constraint\n// Cdot = wB - wA\n// J = [0 0 -1 0 0 1]\n\nexport function b2PrepareWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.wheelJoint;\n\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.axisA = b2RotateVector(qA, joint.localAxisA);\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n\n const d = b2Add(joint.deltaCenter, b2Sub(rB, rA));\n const axisA = joint.axisA;\n const perpA = b2LeftPerp(axisA);\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const kp = mA + mB + iA * s1 * s1 + iB * s2 * s2;\n joint.perpMass = kp > 0.0 ? 1.0 / kp : 0.0;\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n const ka = mA + mB + iA * a1 * a1 + iB * a2 * a2;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n joint.springSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const km = iA + iB;\n joint.motorMass = km > 0.0 ? 1.0 / km : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.perpImpulse = 0.0;\n joint.springImpulse = 0.0;\n joint.motorImpulse = 0.0;\n joint.lowerImpulse = 0.0;\n joint.upperImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWheelJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_wheelJoint);\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const perpA = b2LeftPerp(axisA);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n\n const axialImpulse = joint.springImpulse + joint.lowerImpulse - joint.upperImpulse;\n\n const P = b2Add(b2MulSV(axialImpulse, axisA), b2MulSV(joint.perpImpulse, perpA));\n const LA = axialImpulse * a1 + joint.perpImpulse * s1 + joint.motorImpulse;\n const LB = axialImpulse * a2 + joint.perpImpulse * s2 + joint.motorImpulse;\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, P);\n stateA.angularVelocity -= iA * LA;\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, P);\n stateB.angularVelocity += iB * LB;\n}\n\nexport function b2SolveWheelJoint(base, context, useBias)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.wheelJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n const fixedRotation = (iA + iB === 0.0);\n\n // current anchors\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n const d = b2Add(b2Add(b2Sub(stateB.deltaPosition, stateA.deltaPosition), joint.deltaCenter), b2Sub(rB, rA));\n const axisA = b2RotateVector(stateA.deltaRotation, joint.axisA);\n const translation = b2Dot(axisA, d);\n\n const a1 = b2Cross(b2Add(d, rA), axisA);\n const a2 = b2Cross(rB, axisA);\n\n // motor constraint\n if (joint.enableMotor && fixedRotation === false)\n {\n const Cdot = wB - wA - joint.motorSpeed;\n let impulse = -joint.motorMass * Cdot;\n const oldImpulse = joint.motorImpulse;\n const maxImpulse = context.h * joint.maxMotorTorque;\n joint.motorImpulse = b2ClampFloat(joint.motorImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.motorImpulse - oldImpulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // spring constraint\n if (joint.enableSpring)\n {\n const C = translation;\n const bias = joint.springSoftness.biasRate * C;\n const massScale = joint.springSoftness.massScale;\n const impulseScale = joint.springSoftness.impulseScale;\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.springImpulse;\n joint.springImpulse += impulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n if (joint.enableLimit)\n {\n const translation = b2Dot(axisA, d);\n\n // Lower limit\n {\n const C = translation - joint.lowerTranslation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vB, vA)) + a2 * wB - a1 * wA;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.lowerImpulse;\n const oldImpulse = joint.lowerImpulse;\n joint.lowerImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.lowerImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n // Upper limit\n {\n const C = joint.upperTranslation - translation;\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (C > 0.0)\n {\n // speculation\n bias = C * context.inv_h;\n }\n else if (useBias)\n {\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const Cdot = b2Dot(axisA, b2Sub(vA, vB)) + a1 * wA - a2 * wB;\n let impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.upperImpulse;\n const oldImpulse = joint.upperImpulse;\n joint.upperImpulse = Math.max(oldImpulse + impulse, 0.0);\n impulse = joint.upperImpulse - oldImpulse;\n\n const P = b2MulSV(impulse, axisA);\n const LA = impulse * a1;\n const LB = impulse * a2;\n\n vA = b2MulAdd(vA, mA, P);\n wA += iA * LA;\n vB = b2MulSub(vB, mB, P);\n wB -= iB * LB;\n }\n }\n\n // point to line constraint\n {\n const perpA = b2LeftPerp(axisA);\n\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias)\n {\n const C = b2Dot(perpA, d);\n bias = context.jointSoftness.biasRate * C;\n massScale = context.jointSoftness.massScale;\n impulseScale = context.jointSoftness.impulseScale;\n }\n\n const s1 = b2Cross(b2Add(d, rA), perpA);\n const s2 = b2Cross(rB, perpA);\n const Cdot = b2Dot(perpA, b2Sub(vB, vA)) + s2 * wB - s1 * wA;\n\n const impulse = -massScale * joint.perpMass * (Cdot + bias) - impulseScale * joint.perpImpulse;\n joint.perpImpulse += impulse;\n\n const P = b2MulSV(impulse, perpA);\n const LA = impulse * s1;\n const LB = impulse * s2;\n\n vA = b2MulSub(vA, mA, P);\n wA -= iA * LA;\n vB = b2MulAdd(vB, mB, P);\n wB += iB * LB;\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\n/*\nNOTE: unconverted C code\n\nvoid b2WheelJoint_Dump()\n{\n\tint32 indexA = joint.bodyA.joint.islandIndex;\n\tint32 indexB = joint.bodyB.joint.islandIndex;\n\n\tb2Dump(\" b2WheelJointDef jd;\\n\");\n\tb2Dump(\" jd.bodyA = sims[%d];\\n\", indexA);\n\tb2Dump(\" jd.bodyB = sims[%d];\\n\", indexB);\n\tb2Dump(\" jd.collideConnected = bool(%d);\\n\", joint.collideConnected);\n\tb2Dump(\" jd.localAnchorA.Set(%.9g, %.9g);\\n\", joint.localAnchorA.x, joint.localAnchorA.y);\n\tb2Dump(\" jd.localAnchorB.Set(%.9g, %.9g);\\n\", joint.localAnchorB.x, joint.localAnchorB.y);\n\tb2Dump(\" jd.referenceAngle = %.9g;\\n\", joint.referenceAngle);\n\tb2Dump(\" jd.enableLimit = bool(%d);\\n\", joint.enableLimit);\n\tb2Dump(\" jd.lowerAngle = %.9g;\\n\", joint.lowerAngle);\n\tb2Dump(\" jd.upperAngle = %.9g;\\n\", joint.upperAngle);\n\tb2Dump(\" jd.enableMotor = bool(%d);\\n\", joint.enableMotor);\n\tb2Dump(\" jd.motorSpeed = %.9g;\\n\", joint.motorSpeed);\n\tb2Dump(\" jd.maxMotorTorque = %.9g;\\n\", joint.maxMotorTorque);\n\tb2Dump(\" joints[%d] = joint.world.CreateJoint(&jd);\\n\", joint.index);\n}\n */\n\nexport function b2DrawWheelJoint(draw, base, transformA, transformB)\n{\n console.assert( base.type == b2JointType.b2_wheelJoint );\n\n const joint = base.wheelJoint;\n\n const pA = b2TransformPoint(transformA, base.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, base.localOriginAnchorB);\n const axis = b2RotateVector(transformA.q, joint.localAxisA);\n\n const c1 = b2HexColor.b2_colorGray7;\n const c2 = b2HexColor.b2_colorGreen;\n const c3 = b2HexColor.b2_colorRed;\n const c4 = b2HexColor.b2_colorGray4;\n const c5 = b2HexColor.b2_colorBlue;\n\n draw.DrawSegment(pA, pB, c5, draw.context);\n\n if (joint.enableLimit)\n {\n const lower = b2MulAdd(pA, joint.lowerTranslation, axis);\n const upper = b2MulAdd(pA, joint.upperTranslation, axis);\n const perp = b2LeftPerp(axis);\n draw.DrawSegment(lower, upper, c1, draw.context);\n draw.DrawSegment(b2MulSub(lower, 0.1, perp), b2MulAdd(lower, 0.1, perp), c2, draw.context);\n draw.DrawSegment(b2MulSub(upper, 0.1, perp), b2MulAdd(upper, 0.1, perp), c3, draw.context);\n }\n else\n {\n draw.DrawSegment(b2MulSub(pA, 1.0, axis), b2MulAdd(pA, 1.0, axis), c1, draw.context);\n }\n\n draw.DrawPoint(pA.x, pA.y, 5.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 5.0, c4, draw.context);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_PI,\n b2Add,\n b2ClampFloat,\n b2Cross,\n b2CrossSV,\n b2GetInverse22,\n b2LengthSquared,\n b2MulAdd,\n b2MulMV,\n b2MulSV,\n b2MulSub,\n b2Normalize,\n b2RelativeAngle,\n b2RotateVector,\n b2Sub,\n b2UnwindAngle,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace MotorJoint\n */\n\n/**\n * @summary Sets the target linear offset for a motor joint.\n * @function b2MotorJoint_SetLinearOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {b2Vec2} linearOffset - The desired linear offset in local coordinates.\n * @returns {void}\n * @description\n * Updates the target linear offset of a motor joint. The linear offset represents\n * the desired translation between the two bodies connected by the joint.\n * @throws {Error} Throws if the joint is not a motor joint or if the jointId is invalid.\n */\nexport function b2MotorJoint_SetLinearOffset(jointId, linearOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.linearOffset = linearOffset;\n}\n\n/**\n * Gets the linear offset of a motor joint.\n * @function b2MotorJoint_GetLinearOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {b2Vec2} The linear offset vector of the motor joint.\n * @throws {Error} If the joint is not a motor joint or the joint ID is invalid.\n */\nexport function b2MotorJoint_GetLinearOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.linearOffset;\n}\n\n/**\n * @summary Sets the target angular offset for a motor joint.\n * @function b2MotorJoint_SetAngularOffset\n * @param {b2JointId} jointId - The identifier for the motor joint to modify.\n * @param {number} angularOffset - The desired angular offset in radians, clamped between -\u03C0 and \u03C0.\n * @returns {void}\n * @description\n * Sets the target angular offset for a motor joint, which defines the desired relative rotation\n * between the connected bodies. The input angle is automatically clamped to the range [-\u03C0, \u03C0].\n * @throws {Error} Throws if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetAngularOffset(jointId, angularOffset)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.angularOffset = b2ClampFloat(angularOffset, -B2_PI, B2_PI);\n}\n\n/**\n * @summary Gets the angular offset of a motor joint.\n * @function b2MotorJoint_GetAngularOffset\n * @param {b2JointId} jointId - The identifier of the motor joint.\n * @returns {number} The angular offset value of the motor joint in radians.\n * @throws {Error} Throws if the joint is not a motor joint or if the joint ID is invalid.\n */\nexport function b2MotorJoint_GetAngularOffset(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.angularOffset;\n}\n\n/**\n * Sets the maximum force that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint\n * @param {number} maxForce - The maximum force value to set. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not a motor joint type\n */\nexport function b2MotorJoint_SetMaxForce(jointId, maxForce)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxForce = Math.max(0.0, maxForce);\n}\n\n/**\n * Gets the maximum force value from a motor joint.\n * @function b2MotorJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum force value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxForce(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxForce;\n}\n\n/**\n * Sets the maximum torque that can be applied by a motor joint.\n * @function b2MotorJoint_SetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} maxTorque - The maximum torque value. Will be clamped to non-negative values.\n * @returns {void}\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_SetMaxTorque(jointId, maxTorque)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.maxTorque = Math.max(0.0, maxTorque);\n}\n\n/**\n * Gets the maximum torque value for a motor joint.\n * @function b2MotorJoint_GetMaxTorque\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The maximum torque value of the motor joint.\n * @throws {Error} If the joint is not of type b2_motorJoint.\n */\nexport function b2MotorJoint_GetMaxTorque(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.maxTorque;\n}\n\n/**\n * @function b2MotorJoint_SetCorrectionFactor\n * @summary Sets the position correction factor for a motor joint.\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @param {number} correctionFactor - The correction factor value, clamped between 0 and 1.\n * @returns {void}\n * @description\n * Sets the position correction factor for a motor joint, which determines how much position error is corrected each time step.\n * The correction factor is automatically clamped between 0 and 1.\n * @throws {Error} Throws an error if the joint is not a motor joint type.\n */\nexport function b2MotorJoint_SetCorrectionFactor(jointId, correctionFactor)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n joint.motorJoint.correctionFactor = b2ClampFloat(correctionFactor, 0.0, 1.0);\n}\n\n/**\n * Gets the correction factor of a motor joint.\n * @function b2MotorJoint_GetCorrectionFactor\n * @param {b2JointId} jointId - The identifier for the motor joint.\n * @returns {number} The correction factor value of the motor joint.\n * @throws {Error} If the joint is not a motor joint type.\n */\nexport function b2MotorJoint_GetCorrectionFactor(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_motorJoint);\n\n return joint.motorJoint.correctionFactor;\n}\n\nexport function b2GetMotorJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.motorJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMotorJointTorque(world, base)\n{\n return world.inv_h * base.motorJoint.angularImpulse;\n}\n\n// Point-to-point constraint\n// C = p2 - p1\n// Cdot = v2 - v1\n// = v2 + cross(w2, r2) - v1 - cross(w1, r1)\n// J = [-I -r1_skew I r2_skew ]\n// Identity used:\n// w k % (rx i + ry j) = w * (-ry i + rx j)\n// Angle constraint\n// C = angle2 - angle1 - referenceAngle\n// Cdot = w2 - w1\n// J = [0 0 -1 0 0 1]\n// K = invI1 + invI2\n\nexport function b2PrepareMotorJoint(base, context)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n console.assert(bodyA.setIndex == b2SetType.b2_awakeSet || bodyB.setIndex == b2SetType.b2_awakeSet);\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n console.assert(0 <= localIndexA && localIndexA <= setA.sims.count);\n console.assert(0 <= localIndexB && localIndexB <= setB.sims.count);\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n const joint = base.motorJoint;\n joint.indexA = bodyA.setIndex == b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex == b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorA = b2RotateVector(bodySimA.transform.q, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(b2Sub(bodySimB.center, bodySimA.center), joint.linearOffset);\n joint.deltaAngle = b2RelativeAngle(bodySimB.transform.q, bodySimA.transform.q) - joint.angularOffset;\n joint.deltaAngle = b2UnwindAngle(joint.deltaAngle);\n const rA = joint.anchorA;\n const rB = joint.anchorB;\n const K = {\n cx: new b2Vec2(0, 0),\n cy: new b2Vec2(0, 0)\n };\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cx.y = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cy.x = K.cx.y;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n joint.linearMass = b2GetInverse22(K);\n const ka = iA + iB;\n joint.angularMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (context.enableWarmStarting == false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMotorJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n const joint = base.motorJoint;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n bodyA.linearVelocity = b2MulSub(bodyA.linearVelocity, mA, joint.linearImpulse);\n bodyA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n bodyB.linearVelocity = b2MulAdd(bodyB.linearVelocity, mB, joint.linearImpulse);\n bodyB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveMotorJoint(base, context, useBias)\n{\n console.assert(base.type == b2JointType.b2_motorJoint);\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n const joint = base.motorJoint;\n const bodyA = joint.indexA == B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const bodyB = joint.indexB == B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n let vA = bodyA.linearVelocity;\n let wA = bodyA.angularVelocity;\n let vB = bodyB.linearVelocity;\n let wB = bodyB.angularVelocity;\n\n // angular constraint\n {\n let angularSeperation = b2RelativeAngle(bodyB.deltaRotation, bodyA.deltaRotation) + joint.deltaAngle;\n angularSeperation = b2UnwindAngle(angularSeperation);\n const angularBias = context.inv_h * joint.correctionFactor * angularSeperation;\n const Cdot = wB - wA;\n let impulse = -joint.angularMass * (Cdot + angularBias);\n const oldImpulse = joint.angularImpulse;\n const maxImpulse = context.h * joint.maxTorque;\n joint.angularImpulse = b2ClampFloat(joint.angularImpulse + impulse, -maxImpulse, maxImpulse);\n impulse = joint.angularImpulse - oldImpulse;\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(bodyA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(bodyB.deltaRotation, joint.anchorB);\n const ds = b2Add(b2Sub(bodyB.deltaPosition, bodyA.deltaPosition), b2Sub(rB, rA));\n const linearSeparation = b2Add(joint.deltaCenter, ds);\n const linearBias = b2MulSV(context.inv_h * joint.correctionFactor, linearSeparation);\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, linearBias));\n let impulse = new b2Vec2(-b.x, -b.y);\n const oldImpulse = joint.linearImpulse;\n const maxImpulse = context.h * joint.maxForce;\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n if (b2LengthSquared(joint.linearImpulse) > maxImpulse * maxImpulse)\n {\n joint.linearImpulse = b2Normalize(joint.linearImpulse);\n joint.linearImpulse.x *= maxImpulse;\n joint.linearImpulse.y *= maxImpulse;\n }\n impulse = b2Sub(joint.linearImpulse, oldImpulse);\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n bodyA.linearVelocity = vA;\n bodyA.angularVelocity = wA;\n bodyB.linearVelocity = vB;\n bodyB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Cross, b2CrossSV, b2GetInverse22, b2Length, b2MulAdd, b2MulMV, b2MulSV, b2Normalize, b2RotateVector, b2Sub, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2GetJointSimCheckType, b2Joint_WakeBodies } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2JointType } from \"./include/types_h.js\";\nimport { b2MakeSoft } from \"./include/solver_h.js\";\nimport { b2SetType } from \"./include/world_h.js\";\n\n/**\n * @namespace MouseJoint\n */\n\n/**\n * @summary Sets the target position for a mouse joint.\n * @function b2MouseJoint_SetTarget\n * @param {b2JointId} jointId - The identifier of the mouse joint to modify.\n * @param {b2Vec2} target - The new target position vector to set.\n * @returns {void}\n * @description\n * Updates the target position of a mouse joint by cloning the provided target vector.\n * The joint must be of type b2_mouseJoint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetTarget(jointId, target)\n{\n // b2Vec2_IsValid(target);\n b2Joint_WakeBodies(jointId);\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.targetA = target.clone();\n}\n\n/**\n * @function b2MouseJoint_GetTarget\n * @summary Gets the target point of a mouse joint.\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {b2Vec2} The target point of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetTarget(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.targetA;\n}\n\n/**\n * @summary Sets the spring frequency (in Hertz) for a mouse joint.\n * @function b2MouseJoint_SetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} hertz - The spring frequency in Hertz (Hz).\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringHertz(jointId, hertz)\n{\n // b2IsValid(hertz) && hertz >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.hertz = hertz;\n}\n\n/**\n * Gets the spring frequency in Hertz from a mouse joint.\n * @function b2MouseJoint_GetSpringHertz\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The spring frequency in Hertz.\n * @throws {Error} If the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringHertz(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.hertz;\n}\n\n/**\n * Sets the damping ratio for a mouse joint.\n * @function b2MouseJoint_SetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} dampingRatio - The damping ratio value to set.\n * @returns {void}\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_SetSpringDampingRatio(jointId, dampingRatio)\n{\n // b2IsValid(dampingRatio) && dampingRatio >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.dampingRatio = dampingRatio;\n}\n\n/**\n * Gets the spring damping ratio of a mouse joint.\n * @function b2MouseJoint_GetSpringDampingRatio\n * @param {b2JointId} jointId - The identifier of the mouse joint.\n * @returns {number} The spring damping ratio value of the mouse joint.\n * @throws {Error} Throws if the joint is not a mouse joint type.\n */\nexport function b2MouseJoint_GetSpringDampingRatio(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.dampingRatio;\n}\n\n/**\n * @summary Sets the maximum force for a mouse joint.\n * @function b2MouseJoint_SetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint to modify.\n * @param {number} maxForce - The maximum force value to set for the joint.\n * @returns {void}\n * @description\n * Sets the maximum force that can be applied by the mouse joint to maintain its constraint.\n * @throws {Error} Throws an error if the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_SetMaxForce(jointId, maxForce)\n{\n // b2IsValid(maxForce) && maxForce >= 0.0;\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n base.mouseJoint.maxForce = maxForce;\n}\n\n/**\n * Gets the maximum force value from a mouse joint.\n * @function b2MouseJoint_GetMaxForce\n * @param {b2JointId} jointId - The identifier for the mouse joint.\n * @returns {number} The maximum force value of the mouse joint.\n * @throws {Error} If the joint is not of type b2_mouseJoint.\n */\nexport function b2MouseJoint_GetMaxForce(jointId)\n{\n const base = b2GetJointSimCheckType(jointId, b2JointType.b2_mouseJoint);\n\n return base.mouseJoint.maxForce;\n}\n\nexport function b2GetMouseJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.mouseJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetMouseJointTorque(world, base)\n{\n return world.inv_h * base.mouseJoint.angularImpulse;\n}\n\nexport function b2PrepareMouseJoint(base, context)\n{\n // base.type === b2JointType.b2_mouseJoint;\n\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idB);\n\n const bodyB = bodies[idB];\n\n bodyB.setIndex === b2SetType.b2_awakeSet;\n\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexB = bodyB.localIndex;\n\n // 0 <= localIndexB && localIndexB <= setB.sims.count;\n\n const bodySimB = setB.sims.data[localIndexB];\n\n base.invMassB = bodySimB.invMass;\n base.invIB = bodySimB.invInertia;\n\n const joint = base.mouseJoint;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n joint.anchorB = b2RotateVector(bodySimB.transform.q, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n\n joint.linearSoftness = b2MakeSoft(joint.hertz, joint.dampingRatio, context.h);\n\n const angularHertz = 0.5;\n const angularDampingRatio = 0.1;\n joint.angularSoftness = b2MakeSoft(angularHertz, angularDampingRatio, context.h);\n\n const rB = joint.anchorB;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n const K = {\n cx: new b2Vec2(mB + iB * rB.y * rB.y, -iB * rB.x * rB.y),\n cy: new b2Vec2(-iB * rB.x * rB.y, mB + iB * rB.x * rB.x)\n };\n\n joint.linearMass = b2GetInverse22(K);\n joint.deltaCenter = b2Sub(bodySimB.center, joint.targetA);\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartMouseJoint(base, context)\n{\n base.type === b2JointType.b2_mouseJoint;\n\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n\n const stateB = context.states[joint.indexB];\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n\n vB = b2MulAdd(vB, mB, joint.linearImpulse);\n wB += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n\nexport function b2SolveMouseJoint(base, context)\n{\n const mB = base.invMassB;\n const iB = base.invIB;\n\n const joint = base.mouseJoint;\n const stateB = context.states[joint.indexB];\n\n let vB = stateB.linearVelocity.clone();\n let wB = stateB.angularVelocity;\n\n {\n const massScale = joint.angularSoftness.massScale;\n const impulseScale = joint.angularSoftness.impulseScale;\n\n let impulseStrength = iB > 0.0 ? -wB / iB : 0.0;\n impulseStrength = massScale * impulseStrength - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulseStrength;\n\n wB += iB * impulseStrength;\n }\n\n const maxImpulse = joint.maxForce * context.h;\n\n {\n const dqB = stateB.deltaRotation;\n const rB = b2RotateVector(dqB, joint.anchorB);\n const Cdot = b2Add(vB, b2CrossSV(wB, rB));\n\n const separation = b2Add(b2Add(stateB.deltaPosition, rB), joint.deltaCenter);\n const bias = b2MulSV(joint.linearSoftness.biasRate, separation);\n\n const massScale = joint.linearSoftness.massScale;\n const impulseScale = joint.linearSoftness.impulseScale;\n\n const b = b2MulMV(joint.linearMass, b2Add(Cdot, bias));\n\n const impulseVector = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n const oldImpulse = joint.linearImpulse.clone();\n joint.linearImpulse.x += impulseVector.x;\n joint.linearImpulse.y += impulseVector.y;\n\n const mag = b2Length(joint.linearImpulse);\n\n if (mag > maxImpulse)\n {\n joint.linearImpulse = b2MulSV(maxImpulse, b2Normalize(joint.linearImpulse));\n }\n\n impulseVector.x = joint.linearImpulse.x - oldImpulse.x;\n impulseVector.y = joint.linearImpulse.y - oldImpulse.y;\n\n vB = b2MulAdd(vB, mB, impulseVector);\n wB += iB * b2Cross(rB, impulseVector);\n }\n\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n b2Add,\n b2Cross,\n b2CrossSV,\n b2IsValid,\n b2Mat22,\n b2MulAdd,\n b2MulSV,\n b2MulSub,\n b2RelativeAngle,\n b2RotateVector,\n b2Solve22,\n b2Sub,\n b2Vec2\n} from './include/math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2BodyState } from './include/body_h.js';\nimport { b2GetJointSimCheckType } from './include/joint_h.js';\nimport { b2JointType } from './include/types_h.js';\nimport { b2MakeSoft } from './include/solver_h.js';\nimport { b2SetType } from './include/world_h.js';\n\n/**\n * @namespace WeldJoint\n */\n\n/**\n * Sets the linear frequency (hertz) for a weld joint.\n * @function b2WeldJoint_SetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify\n * @param {number} hertz - The frequency in hertz (must be >= 0)\n * @returns {void}\n * @throws {Error} If the hertz value is invalid or negative\n */\nexport function b2WeldJoint_SetLinearHertz(jointId, hertz)\n{\n // Assert is not directly translatable to JS, so we'll use a simple if check\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearHertz = hertz;\n}\n\n/**\n * Gets the linear Hertz value from a weld joint.\n * @function b2WeldJoint_GetLinearHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear Hertz value of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearHertz;\n}\n\n/**\n * Sets the linear damping ratio for a weld joint.\n * @function b2WeldJoint_SetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The damping ratio value. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetLinearDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.linearDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the linear damping ratio of a weld joint.\n * @function b2WeldJoint_GetLinearDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The linear damping ratio of the weld joint.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetLinearDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.linearDampingRatio;\n}\n\n/**\n * Sets the angular frequency (hertz) for a weld joint's angular spring-damper.\n * @function b2WeldJoint_SetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} hertz - The angular frequency in Hertz (must be >= 0).\n * @returns {void}\n * @throws {Error} If the hertz value is invalid (NaN, negative, or infinity).\n * @throws {Error} If the joint is not a weld joint.\n */\nexport function b2WeldJoint_SetAngularHertz(jointId, hertz)\n{\n if (!(b2IsValid(hertz) && hertz >= 0.0))\n {\n throw new Error(\"Invalid hertz value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularHertz = hertz;\n}\n\n/**\n * Gets the angular frequency (hertz) of a weld joint.\n * @function b2WeldJoint_GetAngularHertz\n * @param {b2JointId} jointId - The identifier for the weld joint.\n * @returns {number} The angular frequency in hertz.\n * @throws {Error} If the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularHertz(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularHertz;\n}\n\n/**\n * Sets the angular damping ratio for a weld joint.\n * @function b2WeldJoint_SetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier for the weld joint to modify.\n * @param {number} dampingRatio - The angular damping ratio. Must be non-negative.\n * @returns {void}\n * @throws {Error} If dampingRatio is invalid or negative.\n */\nexport function b2WeldJoint_SetAngularDampingRatio(jointId, dampingRatio)\n{\n if (!(b2IsValid(dampingRatio) && dampingRatio >= 0.0))\n {\n throw new Error(\"Invalid dampingRatio value\");\n }\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n joint.weldJoint.angularDampingRatio = dampingRatio;\n}\n\n/**\n * Gets the angular damping ratio of a weld joint.\n * @function b2WeldJoint_GetAngularDampingRatio\n * @param {b2JointId} jointId - The identifier of the weld joint.\n * @returns {number} The angular damping ratio of the weld joint.\n * @throws {Error} Throws an error if the joint is not of type b2_weldJoint.\n */\nexport function b2WeldJoint_GetAngularDampingRatio(jointId)\n{\n const joint = b2GetJointSimCheckType(jointId, b2JointType.b2_weldJoint);\n\n return joint.weldJoint.angularDampingRatio;\n}\n\nexport function b2GetWeldJointForce(world, base)\n{\n const force = b2MulSV(world.inv_h, base.weldJoint.linearImpulse);\n\n return force;\n}\n\nexport function b2GetWeldJointTorque(world, base)\n{\n return world.inv_h * base.weldJoint.angularImpulse;\n}\n\nexport function b2PrepareWeldJoint(base, context)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const idA = base.bodyIdA;\n const idB = base.bodyIdB;\n\n const world = context.world;\n const bodies = world.bodyArray;\n\n // b2CheckIndex(bodies, idA);\n // b2CheckIndex(bodies, idB);\n\n const bodyA = bodies[idA];\n const bodyB = bodies[idB];\n\n if (!(bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet))\n {\n throw new Error(\"At least one body must be awake\");\n }\n\n // b2CheckIndex(world.solverSetArray, bodyA.setIndex);\n // b2CheckIndex(world.solverSetArray, bodyB.setIndex);\n\n const setA = world.solverSetArray[bodyA.setIndex];\n const setB = world.solverSetArray[bodyB.setIndex];\n\n const localIndexA = bodyA.localIndex;\n const localIndexB = bodyB.localIndex;\n\n if (!(0 <= localIndexA && localIndexA <= setA.sims.count))\n {\n throw new Error(\"Invalid localIndexA\");\n }\n\n if (!(0 <= localIndexB && localIndexB <= setB.sims.count))\n {\n throw new Error(\"Invalid localIndexB\");\n }\n\n const bodySimA = setA.sims.data[bodyA.localIndex];\n const bodySimB = setB.sims.data[bodyB.localIndex];\n\n const mA = bodySimA.invMass;\n const iA = bodySimA.invInertia;\n const mB = bodySimB.invMass;\n const iB = bodySimB.invInertia;\n\n base.invMassA = mA;\n base.invMassB = mB;\n base.invIA = iA;\n base.invIB = iB;\n\n const joint = base.weldJoint;\n joint.indexA = bodyA.setIndex === b2SetType.b2_awakeSet ? localIndexA : B2_NULL_INDEX;\n joint.indexB = bodyB.setIndex === b2SetType.b2_awakeSet ? localIndexB : B2_NULL_INDEX;\n\n const qA = bodySimA.transform.q;\n const qB = bodySimB.transform.q;\n\n joint.anchorA = b2RotateVector(qA, b2Sub(base.localOriginAnchorA, bodySimA.localCenter));\n joint.anchorB = b2RotateVector(qB, b2Sub(base.localOriginAnchorB, bodySimB.localCenter));\n joint.deltaCenter = b2Sub(bodySimB.center, bodySimA.center);\n joint.deltaAngle = b2RelativeAngle(qB, qA) - joint.referenceAngle;\n\n const ka = iA + iB;\n joint.axialMass = ka > 0.0 ? 1.0 / ka : 0.0;\n\n if (joint.linearHertz === 0.0)\n {\n joint.linearSoftness = context.jointSoftness;\n }\n else\n {\n joint.linearSoftness = b2MakeSoft(joint.linearHertz, joint.linearDampingRatio, context.h);\n }\n\n if (joint.angularHertz === 0.0)\n {\n joint.angularSoftness = context.jointSoftness;\n }\n else\n {\n joint.angularSoftness = b2MakeSoft(joint.angularHertz, joint.angularDampingRatio, context.h);\n }\n\n if (context.enableWarmStarting === false)\n {\n joint.linearImpulse = new b2Vec2(0, 0);\n joint.angularImpulse = 0.0;\n }\n}\n\nexport function b2WarmStartWeldJoint(base, context)\n{\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n stateA.linearVelocity = b2MulSub(stateA.linearVelocity, mA, joint.linearImpulse);\n stateA.angularVelocity -= iA * (b2Cross(rA, joint.linearImpulse) + joint.angularImpulse);\n\n stateB.linearVelocity = b2MulAdd(stateB.linearVelocity, mB, joint.linearImpulse);\n stateB.angularVelocity += iB * (b2Cross(rB, joint.linearImpulse) + joint.angularImpulse);\n}\n\nexport function b2SolveWeldJoint(base, context, useBias)\n{\n if (base.type !== b2JointType.b2_weldJoint)\n {\n throw new Error(\"Invalid joint type\");\n }\n\n const mA = base.invMassA;\n const mB = base.invMassB;\n const iA = base.invIA;\n const iB = base.invIB;\n\n // dummy state for static bodies\n const dummyState = new b2BodyState();\n\n const joint = base.weldJoint;\n\n const stateA = joint.indexA === B2_NULL_INDEX ? dummyState : context.states[joint.indexA];\n const stateB = joint.indexB === B2_NULL_INDEX ? dummyState : context.states[joint.indexB];\n\n let vA = stateA.linearVelocity;\n let wA = stateA.angularVelocity;\n let vB = stateB.linearVelocity;\n let wB = stateB.angularVelocity;\n\n // angular constraint\n {\n let bias = 0.0;\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.angularHertz > 0.0)\n {\n const C = b2RelativeAngle(stateB.deltaRotation, stateA.deltaRotation) + joint.deltaAngle;\n bias = joint.angularSoftness.biasRate * C;\n massScale = joint.angularSoftness.massScale;\n impulseScale = joint.angularSoftness.impulseScale;\n }\n\n const Cdot = wB - wA;\n const impulse = -massScale * joint.axialMass * (Cdot + bias) - impulseScale * joint.angularImpulse;\n joint.angularImpulse += impulse;\n\n wA -= iA * impulse;\n wB += iB * impulse;\n }\n\n // linear constraint\n {\n const rA = b2RotateVector(stateA.deltaRotation, joint.anchorA);\n const rB = b2RotateVector(stateB.deltaRotation, joint.anchorB);\n\n let bias = new b2Vec2(0, 0);\n let massScale = 1.0;\n let impulseScale = 0.0;\n\n if (useBias || joint.linearHertz > 0.0)\n {\n const dcA = stateA.deltaPosition;\n const dcB = stateB.deltaPosition;\n const C = b2Add(b2Add(b2Sub(dcB, dcA), b2Sub(rB, rA)), joint.deltaCenter);\n\n bias = b2MulSV(joint.linearSoftness.biasRate, C);\n massScale = joint.linearSoftness.massScale;\n impulseScale = joint.linearSoftness.impulseScale;\n }\n\n const Cdot = b2Sub(b2Add(vB, b2CrossSV(wB, rB)), b2Add(vA, b2CrossSV(wA, rA)));\n\n const K = new b2Mat22();\n K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;\n K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;\n K.cx.y = K.cy.x;\n K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;\n const b = b2Solve22(K, b2Add(Cdot, bias));\n\n const impulse = new b2Vec2(\n -massScale * b.x - impulseScale * joint.linearImpulse.x,\n -massScale * b.y - impulseScale * joint.linearImpulse.y);\n\n joint.linearImpulse = b2Add(joint.linearImpulse, impulse);\n\n vA = b2MulSub(vA, mA, impulse);\n wA -= iA * b2Cross(rA, impulse);\n vB = b2MulAdd(vB, mB, impulse);\n wB += iB * b2Cross(rB, impulse);\n }\n\n stateA.linearVelocity = vA;\n stateA.angularVelocity = wA;\n stateB.linearVelocity = vB;\n stateB.angularVelocity = wB;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_linearSlop } from \"./include/core_h.js\";\nimport { b2AddJoint, b2RemoveJoint } from \"./include/block_array_h.js\";\nimport { b2AllocId, b2FreeId } from \"./include/id_pool_h.js\";\nimport { b2Body_IsValid, b2GetWorld, b2GetWorldFromId, b2GetWorldLocked, b2SetType, b2ValidateSolverSets } from \"./include/world_h.js\";\nimport { b2ClampFloat, b2InvTransformPoint, b2IsValid, b2Lerp, b2Normalize, b2TransformPoint, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2CreateJointInGraph, b2RemoveJointFromGraph, b2_overflowIndex } from \"./include/constraint_graph_h.js\";\nimport { b2DistanceJoint, b2Joint, b2JointEdge, b2MotorJoint, b2MouseJoint, b2PrismaticJoint, b2RevoluteJoint, b2WeldJoint, b2WheelJoint } from \"./include/joint_h.js\";\nimport { b2DistanceJointDef, b2HexColor, b2JointType, b2MotorJointDef, b2MouseJointDef, b2PrismaticJointDef, b2RevoluteJointDef, b2WeldJointDef, b2WheelJointDef } from \"./include/types_h.js\";\nimport { b2DrawDistanceJoint, b2GetDistanceJointForce, b2PrepareDistanceJoint, b2SolveDistanceJoint, b2WarmStartDistanceJoint } from \"./include/distance_joint_h.js\";\nimport { b2DrawPrismaticJoint, b2GetPrismaticJointForce, b2GetPrismaticJointTorque, b2PreparePrismaticJoint, b2SolvePrismaticJoint, b2WarmStartPrismaticJoint } from \"./include/prismatic_joint_h.js\";\nimport { b2DrawRevoluteJoint, b2PrepareRevoluteJoint, b2SolveRevoluteJoint, b2WarmStartRevoluteJoint } from \"./include/revolute_joint_h.js\";\nimport { b2DrawWheelJoint, b2PrepareWheelJoint, b2SolveWheelJoint, b2WarmStartWheelJoint } from \"./include/wheel_joint_h.js\";\nimport { b2GetBody, b2GetBodyFullId, b2GetBodyTransformQuick, b2MakeBodyId, b2WakeBody } from \"./include/body_h.js\";\nimport { b2GetMotorJointForce, b2GetMotorJointTorque } from \"./include/motor_joint_h.js\";\nimport { b2GetMouseJointForce, b2GetMouseJointTorque, b2PrepareMouseJoint, b2SolveMouseJoint, b2WarmStartMouseJoint } from \"./include/mouse_joint_h.js\";\nimport { b2GetRevoluteJointForce, b2GetRevoluteJointTorque } from \"./include/revolute_joint_h.js\";\nimport { b2GetWeldJointForce, b2GetWeldJointTorque } from \"./include/weld_joint_h.js\";\nimport { b2GetWheelJointForce, b2GetWheelJointTorque } from \"./include/wheel_joint_h.js\";\nimport { b2LinkJoint, b2UnlinkJoint } from \"./include/island_h.js\";\nimport { b2MergeSolverSets, b2WakeSolverSet } from \"./include/solver_set_h.js\";\nimport { b2PrepareMotorJoint, b2SolveMotorJoint, b2WarmStartMotorJoint } from \"./include/motor_joint_h.js\";\nimport { b2PrepareWeldJoint, b2SolveWeldJoint, b2WarmStartWeldJoint } from \"./include/weld_joint_h.js\";\n\nimport { b2BufferMove } from \"./include/broad_phase_h.js\";\nimport { b2DestroyContact } from \"./include/contact_h.js\";\nimport { b2JointId, b2WorldId } from \"./include/id_h.js\";\n\n/**\n * @namespace Joint\n */\n\n/**\n * Creates a default distance joint definition with preset values.\n * @function b2DefaultDistanceJointDef\n * @returns {b2DistanceJointDef} A distance joint definition with:\n * - length set to 1\n * - maxLength set to B2_HUGE\n * - all other properties at their default values\n * @description\n * Creates and returns a new b2DistanceJointDef object initialized with specific default values.\n * The length is set to 1 unit and the maxLength is set to B2_HUGE. All other properties\n * of the joint definition retain their default values from the b2DistanceJointDef constructor.\n */\nexport function b2DefaultDistanceJointDef()\n{\n const def = new b2DistanceJointDef();\n def.length = 1.0;\n def.maxLength = B2_HUGE;\n\n return def;\n}\n\n/**\n * Creates a b2MotorJointDef with default values.\n * @function b2DefaultMotorJointDef\n * @returns {b2MotorJointDef} A motor joint definition with:\n * - maxForce: 1\n * - maxTorque: 1\n * - correctionFactor: 0.3\n * - linearOffset: (0,0)\n * - angularOffset: 0\n * @description\n * Initializes a new b2MotorJointDef with common default values.\n * The joint definition includes preset values for maximum force,\n * maximum torque, and correction factor while using default\n * values for linear and angular offsets.\n */\nexport function b2DefaultMotorJointDef()\n{\n const def = new b2MotorJointDef();\n def.maxForce = 1.0;\n def.maxTorque = 1.0;\n def.correctionFactor = 0.3;\n\n return def;\n}\n\n/**\n * Creates a b2MouseJointDef with default settings.\n * @function b2DefaultMouseJointDef\n * @returns {b2MouseJointDef} A mouse joint definition with:\n * - hertz = 4\n * - dampingRatio = 1\n * - maxForce = 1\n * @description\n * Creates and returns a new b2MouseJointDef object initialized with default values\n * for frequency (hertz), damping ratio, and maximum force parameters.\n */\nexport function b2DefaultMouseJointDef()\n{\n const def = new b2MouseJointDef();\n def.hertz = 4.0;\n def.dampingRatio = 1.0;\n def.maxForce = 1.0;\n\n return def;\n}\n\n/**\n * Creates a default prismatic joint definition with preset values.\n * @function b2DefaultPrismaticJointDef\n * @returns {b2PrismaticJointDef} A prismatic joint definition with localAxisA set to (1,0)\n * @description\n * Creates and returns a new b2PrismaticJointDef instance with localAxisA initialized\n * to a unit vector pointing along the x-axis (1,0). All other properties retain their\n * default values from the b2PrismaticJointDef constructor.\n */\nexport function b2DefaultPrismaticJointDef()\n{\n const def = new b2PrismaticJointDef();\n def.localAxisA = new b2Vec2(1.0, 0.0);\n\n return def;\n}\n\n/**\n * Creates a default b2RevoluteJointDef with preset values.\n * @function b2DefaultRevoluteJointDef\n * @returns {b2RevoluteJointDef} A new revolution joint definition with drawSize set to 0.25\n * @description\n * Creates and initializes a new b2RevoluteJointDef with default values.\n * Sets the drawSize property to 0.25 for visualization purposes.\n */\nexport function b2DefaultRevoluteJointDef()\n{\n const def = new b2RevoluteJointDef();\n def.drawSize = 0.25;\n\n return def;\n}\n\n/**\n * @summary Creates a new weld joint definition with default values.\n * @function b2DefaultWeldJointDef\n * @returns {b2WeldJointDef} A new weld joint definition with default configuration:\n * - localAnchorA: b2Vec2(0,0)\n * - localAnchorB: b2Vec2(0,0)\n * - referenceAngle: 0\n * - stiffness: 0\n * - damping: 0\n * @description\n * Creates and returns a new b2WeldJointDef object initialized with default values.\n * A weld joint essentially glues two bodies together at a reference point.\n */\nexport function b2DefaultWeldJointDef()\n{\n return new b2WeldJointDef();\n}\n\n/**\n * Creates a default wheel joint definition with preset values.\n * @function b2DefaultWheelJointDef\n * @returns {b2WheelJointDef} A wheel joint definition with:\n * - localAxisA set to (0,1)\n * - enableSpring set to true\n * - hertz set to 1\n * - dampingRatio set to 0.7\n * @description\n * Creates and returns a new b2WheelJointDef with common default values.\n * The joint's local axis is set to point upward, and spring behavior\n * is enabled with standard frequency and damping values.\n */\nexport function b2DefaultWheelJointDef()\n{\n const def = new b2WheelJointDef();\n def.localAxisA = new b2Vec2(0.0, 1.0);\n def.enableSpring = true;\n def.hertz = 1.0;\n def.dampingRatio = 0.7;\n\n return def;\n}\n\nfunction b2GetJointFullId(world, jointId)\n{\n const id = jointId.index1 - 1;\n\n // b2CheckIndex(world.jointArray, id);\n const joint = world.jointArray[id];\n\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n console.assert(joint.revision === jointId.revision);\n\n return joint;\n}\n\nexport function b2GetJoint(world, jointId)\n{\n // b2CheckIndex(world.jointArray, jointId);\n return world.jointArray[jointId];\n}\n\nexport function b2GetJointSim(world, joint)\n{\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n\n if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[joint.colorIndex];\n\n // console.assert(0 <= joint.localIndex && joint.localIndex < color.joints.count);\n\n if (joint.jointId !== color.joints.data[joint.localIndex].jointId)\n {\n console.error(\"jointId \" + joint.jointId + \" localIndex \" + joint.localIndex + \" jointSim.jointId \" + color.joints.data[joint.localIndex].jointId);\n\n // debugger;\n }\n\n return color.joints.data[joint.localIndex];\n }\n\n const set = world.solverSetArray[joint.setIndex];\n console.assert(0 <= joint.localIndex && joint.localIndex < set.joints.count);\n console.assert(joint.jointId == set.joints.data[joint.localIndex].jointId);\n\n return set.joints.data[joint.localIndex];\n}\n\nexport function b2GetJointSimCheckType(jointId, type)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return null;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n console.assert(joint.type === type);\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.type === type);\n\n return jointSim;\n}\n\nclass b2JointPair\n{\n constructor(joint = null, jointSim = null)\n {\n this.joint = joint;\n this.jointSim = jointSim;\n \n }\n}\n\nexport function b2CreateJoint(world, bodyA, bodyB, userData, drawSize, type, collideConnected)\n{\n\n b2ValidateSolverSets(world);\n\n const bodyIdA = bodyA.id;\n const bodyIdB = bodyB.id;\n const maxSetIndex = Math.max(bodyA.setIndex, bodyB.setIndex);\n\n // Create joint id and joint\n const jointId = b2AllocId(world.jointIdPool);\n console.assert(jointId !== B2_NULL_INDEX);\n\n // console.warn(\"create jointId \" + jointId + \" world joints \" + world.jointArray.length + \", for body \" + bodyIdA + \" joined to \" + bodyIdB);\n while (jointId >= world.jointArray.length)\n {\n world.jointArray.push(new b2Joint());\n }\n\n const joint = world.jointArray[jointId];\n joint.edges = [ new b2JointEdge(), new b2JointEdge() ];\n joint.jointId = jointId;\n joint.userData = userData;\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n joint.revision += 1;\n joint.drawSize = drawSize;\n joint.type = type;\n joint.isMarked = false;\n joint.collideConnected = collideConnected;\n\n // Doubly linked list on bodyA\n joint.edges[0].bodyId = bodyIdA;\n joint.edges[0].prevKey = B2_NULL_INDEX;\n joint.edges[0].nextKey = bodyA.headJointKey;\n\n const keyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey !== B2_NULL_INDEX)\n {\n const jointA = world.jointArray[bodyA.headJointKey >> 1];\n const edgeA = jointA.edges[bodyA.headJointKey & 1];\n edgeA.prevKey = keyA;\n }\n bodyA.headJointKey = keyA;\n bodyA.jointCount += 1;\n\n // console.warn(\"keyA \" + keyA);\n\n // Doubly linked list on bodyB\n joint.edges[1].bodyId = bodyIdB;\n joint.edges[1].prevKey = B2_NULL_INDEX;\n joint.edges[1].nextKey = bodyB.headJointKey;\n\n const keyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey !== B2_NULL_INDEX)\n {\n const jointB = world.jointArray[bodyB.headJointKey >> 1];\n const edgeB = jointB.edges[bodyB.headJointKey & 1];\n edgeB.prevKey = keyB;\n }\n bodyB.headJointKey = keyB;\n bodyB.jointCount += 1;\n\n // console.warn(\"keyB \" + keyB);\n\n let jointSim;\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // if either body is disabled, create in disabled set\n const set = world.solverSetArray[b2SetType.b2_disabledSet];\n joint.setIndex = b2SetType.b2_disabledSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"disabled \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n // joint is connecting static bodies\n const set = world.solverSetArray[b2SetType.b2_staticSet];\n joint.setIndex = b2SetType.b2_staticSet;\n joint.localIndex = set.joints.length;\n\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"static \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n // if either body is sleeping, wake it\n if (maxSetIndex >= b2SetType.b2_firstSleepingSet)\n {\n // console.warn(\"waking\");\n b2WakeSolverSet(world, maxSetIndex);\n }\n\n joint.setIndex = b2SetType.b2_awakeSet;\n\n jointSim = b2CreateJointInGraph(world, joint);\n jointSim.jointId = jointId;\n\n // console.warn(\"awake \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n }\n else\n {\n // joint connected between sleeping and/or static bodies\n console.assert(bodyA.setIndex >= b2SetType.b2_firstSleepingSet || bodyB.setIndex >= b2SetType.b2_firstSleepingSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n // joint should go into the sleeping set (not static set)\n let setIndex = maxSetIndex;\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n joint.setIndex = setIndex;\n joint.localIndex = set.joints.length;\n jointSim = b2AddJoint(set.joints);\n jointSim.jointId = jointId;\n\n // console.warn(\"else \" + jointId);\n jointSim.bodyIdA = bodyIdA;\n jointSim.bodyIdB = bodyIdB;\n\n if (bodyA.setIndex !== bodyB.setIndex && bodyA.setIndex >= b2SetType.b2_firstSleepingSet &&\n bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // merge sleeping sets\n b2MergeSolverSets(world, bodyA.setIndex, bodyB.setIndex);\n console.assert(bodyA.setIndex === bodyB.setIndex);\n\n // fix potentially invalid set index\n setIndex = bodyA.setIndex;\n\n // Careful! The joint sim pointer was orphaned by the set merge.\n jointSim = world.solverSetArray[setIndex].joints[joint.localIndex];\n }\n\n console.assert(joint.setIndex === setIndex);\n }\n\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === bodyIdA);\n console.assert(jointSim.bodyIdB === bodyIdB);\n\n if (joint.setIndex > b2SetType.b2_disabledSet)\n {\n // Add edge to island graph\n const mergeIslands = true;\n b2LinkJoint(world, joint, mergeIslands);\n }\n\n b2ValidateSolverSets(world);\n\n return new b2JointPair(joint, jointSim);\n}\n\n// Assuming similar data structures exist in JS\n\nexport function b2DestroyContactsBetweenBodies(world, bodyA, bodyB)\n{\n let contactKey;\n let otherBodyId;\n\n if (bodyA.contactCount < bodyB.contactCount)\n {\n contactKey = bodyA.headContactKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n contactKey = bodyB.headContactKey;\n otherBodyId = bodyA.id;\n }\n\n const wakeBodies = false;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n if (contact.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n // Careful, this removes the contact from the current doubly linked list\n b2DestroyContact(world, contact, wakeBodies);\n }\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateDistanceJoint\n * @summary Creates a distance joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2DistanceJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - length: Desired distance between anchor points\n * - minLength: Minimum allowed distance\n * - maxLength: Maximum allowed distance\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - maxMotorForce: Maximum motor force\n * - motorSpeed: Motor speed\n * - enableSpring: Enable/disable spring\n * - enableLimit: Enable/disable length limits\n * - enableMotor: Enable/disable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * @returns {b2JointId} The ID of the created distance joint\n * @throws {Error} Throws assertion error if world is locked, bodies are invalid, or length <= 0\n */\nexport function b2CreateDistanceJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n console.assert(b2Body_IsValid(def.bodyIdA));\n console.assert(b2Body_IsValid(def.bodyIdB));\n console.assert(b2IsValid(def.length) && def.length > 0.0);\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_distanceJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_distanceJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.distanceJoint = new b2DistanceJoint();\n joint.distanceJoint.length = Math.max(def.length, b2_linearSlop);\n joint.distanceJoint.hertz = def.hertz;\n joint.distanceJoint.dampingRatio = def.dampingRatio;\n joint.distanceJoint.minLength = Math.max(def.minLength, b2_linearSlop);\n joint.distanceJoint.maxLength = Math.max(def.minLength, def.maxLength);\n joint.distanceJoint.maxMotorForce = def.maxMotorForce;\n joint.distanceJoint.motorSpeed = def.motorSpeed;\n joint.distanceJoint.enableSpring = def.enableSpring;\n joint.distanceJoint.enableLimit = def.enableLimit;\n joint.distanceJoint.enableMotor = def.enableMotor;\n joint.distanceJoint.impulse = 0.0;\n joint.distanceJoint.lowerImpulse = 0.0;\n joint.distanceJoint.upperImpulse = 0.0;\n joint.distanceJoint.motorImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMotorJoint\n * @summary Creates a motor joint between two bodies in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2MotorJointDef} def - The joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - linearOffset: The target linear offset between bodies\n * - angularOffset: The target angular offset between bodies\n * - maxForce: Maximum force that can be applied\n * - maxTorque: Maximum torque that can be applied\n * - correctionFactor: Position correction factor in [0,1]\n * - collideConnected: Whether bodies can collide\n * - userData: User data\n * @returns {b2JointId} The ID of the created motor joint\n * @throws {Error} If the world is locked when attempting to create the joint\n */\nexport function b2CreateMotorJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_motorJoint, def.collideConnected);\n const joint = pair.jointSim;\n\n joint.type = b2JointType.b2_motorJoint;\n joint.localOriginAnchorA = new b2Vec2(0, 0);\n joint.localOriginAnchorB = new b2Vec2(0, 0);\n joint.motorJoint = new b2MotorJoint();\n joint.motorJoint.linearOffset = def.linearOffset;\n joint.motorJoint.angularOffset = def.angularOffset;\n joint.motorJoint.maxForce = def.maxForce;\n joint.motorJoint.maxTorque = def.maxTorque;\n joint.motorJoint.correctionFactor = b2ClampFloat(def.correctionFactor, 0.0, 1.0);\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateMouseJoint\n * @summary Creates a mouse joint in a Box2D world.\n * @param {b2WorldId} worldId - The ID of the Box2D world where the joint will be created\n * @param {b2MouseJointDef} def - The mouse joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - target: Target point in world coordinates\n * - hertz: Frequency in Hertz\n * - dampingRatio: Damping ratio\n * - maxForce: Maximum force\n * - userData: User data\n * - collideConnected: Whether connected bodies can collide\n * @returns {b2JointId} The ID of the created mouse joint\n * @throws {Error} Throws an assertion error if the world is locked\n * @description\n * Creates a mouse joint between two bodies at a specified target point. The joint\n * transforms the target point into local coordinates for both bodies and initializes\n * the joint properties including frequency, damping ratio, and maximum force.\n */\nexport function b2CreateMouseJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_mouseJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_mouseJoint;\n joint.localOriginAnchorA = b2InvTransformPoint(transformA, def.target);\n joint.localOriginAnchorB = b2InvTransformPoint(transformB, def.target);\n\n joint.mouseJoint = new b2MouseJoint();\n joint.mouseJoint.targetA = def.target;\n joint.mouseJoint.hertz = def.hertz;\n joint.mouseJoint.dampingRatio = def.dampingRatio;\n joint.mouseJoint.maxForce = def.maxForce;\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @summary Creates a revolute joint between two bodies in a Box2D world\n * @function b2CreateRevoluteJoint\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2RevoluteJointDef} def - The joint definition containing properties like:\n * - bodyIdA: ID of first body\n * - bodyIdB: ID of second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Initial angle between bodies (clamped to [-\u03C0,\u03C0])\n * - hertz: Spring frequency\n * - dampingRatio: Spring damping ratio\n * - lowerAngle: Lower angle limit (clamped to [-\u03C0,\u03C0])\n * - upperAngle: Upper angle limit (clamped to [-\u03C0,\u03C0])\n * - maxMotorTorque: Maximum motor torque\n * - motorSpeed: Motor speed\n * - enableSpring: Enable spring behavior\n * - enableLimit: Enable angle limits\n * - enableMotor: Enable motor\n * - collideConnected: Allow collision between connected bodies\n * - userData: User data\n * - drawSize: Drawing size\n * @returns {b2JointId} ID of the created revolute joint\n * @throws {Error} If the world is locked\n */\nexport function b2CreateRevoluteJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, def.drawSize, b2JointType.b2_revoluteJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_revoluteJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.revoluteJoint = new b2RevoluteJoint();\n joint.revoluteJoint.referenceAngle = b2ClampFloat(def.referenceAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.linearImpulse = new b2Vec2(0, 0);\n joint.revoluteJoint.axialMass = 0.0;\n joint.revoluteJoint.springImpulse = 0.0;\n joint.revoluteJoint.motorImpulse = 0.0;\n joint.revoluteJoint.lowerImpulse = 0.0;\n joint.revoluteJoint.upperImpulse = 0.0;\n joint.revoluteJoint.hertz = def.hertz;\n joint.revoluteJoint.dampingRatio = def.dampingRatio;\n joint.revoluteJoint.lowerAngle = Math.min(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.upperAngle = Math.max(def.lowerAngle, def.upperAngle);\n joint.revoluteJoint.lowerAngle = b2ClampFloat(joint.revoluteJoint.lowerAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.upperAngle = b2ClampFloat(joint.revoluteJoint.upperAngle, -Math.PI, Math.PI);\n joint.revoluteJoint.maxMotorTorque = def.maxMotorTorque;\n joint.revoluteJoint.motorSpeed = def.motorSpeed;\n joint.revoluteJoint.enableSpring = def.enableSpring;\n joint.revoluteJoint.enableLimit = def.enableLimit;\n joint.revoluteJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreatePrismaticJoint\n * @description\n * Creates a prismatic joint between two bodies in a Box2D world. A prismatic joint\n * constrains two bodies to move relative to each other along a specified axis.\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2PrismaticJointDef} def - The joint definition containing:\n * - bodyIdA: First body ID\n * - bodyIdB: Second body ID\n * - localAnchorA: Anchor point on body A in local coordinates\n * - localAnchorB: Anchor point on body B in local coordinates\n * - localAxisA: The axis of translation in body A's local coordinates\n * - referenceAngle: The initial angle between the bodies\n * - enableLimit: Whether translation limits are enabled\n * - lowerTranslation: Lower translation limit\n * - upperTranslation: Upper translation limit\n * - enableMotor: Whether the motor is enabled\n * - motorSpeed: Motor speed\n * - maxMotorForce: Maximum motor force\n * - enableSpring: Whether spring is enabled\n * - hertz: Spring frequency in Hz\n * - dampingRatio: Spring damping ratio\n * - collideConnected: Whether connected bodies can collide\n * - userData: User data\n * @returns {b2JointId} The identifier for the created prismatic joint\n */\nexport function b2CreatePrismaticJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_prismaticJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_prismaticJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.prismaticJoint = new b2PrismaticJoint();\n joint.prismaticJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.prismaticJoint.referenceAngle = def.referenceAngle;\n joint.prismaticJoint.impulse = new b2Vec2(0, 0);\n joint.prismaticJoint.axialMass = 0.0;\n joint.prismaticJoint.springImpulse = 0.0;\n joint.prismaticJoint.motorImpulse = 0.0;\n joint.prismaticJoint.lowerImpulse = 0.0;\n joint.prismaticJoint.upperImpulse = 0.0;\n joint.prismaticJoint.hertz = def.hertz;\n joint.prismaticJoint.dampingRatio = def.dampingRatio;\n joint.prismaticJoint.lowerTranslation = def.lowerTranslation;\n joint.prismaticJoint.upperTranslation = def.upperTranslation;\n joint.prismaticJoint.maxMotorForce = def.maxMotorForce;\n joint.prismaticJoint.motorSpeed = def.motorSpeed;\n joint.prismaticJoint.enableSpring = def.enableSpring;\n joint.prismaticJoint.enableLimit = def.enableLimit;\n joint.prismaticJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * Creates a weld joint between two bodies in a Box2D world.\n * @function b2CreateWeldJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WeldJointDef} def - The weld joint definition containing:\n * - bodyIdA: ID of the first body\n * - bodyIdB: ID of the second body\n * - localAnchorA: Local anchor point on body A\n * - localAnchorB: Local anchor point on body B\n * - referenceAngle: Reference angle between the bodies\n * - linearHertz: Frequency for the linear constraint\n * - linearDampingRatio: Damping ratio for the linear constraint\n * - angularHertz: Frequency for the angular constraint\n * - angularDampingRatio: Damping ratio for the angular constraint\n * - collideConnected: Whether the connected bodies can collide\n * - userData: User data associated with the joint\n * @returns {b2JointId} The identifier of the created weld joint\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2CreateWeldJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_weldJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_weldJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.weldJoint = new b2WeldJoint();\n joint.weldJoint.referenceAngle = def.referenceAngle;\n joint.weldJoint.linearHertz = def.linearHertz;\n joint.weldJoint.linearDampingRatio = def.linearDampingRatio;\n joint.weldJoint.angularHertz = def.angularHertz;\n joint.weldJoint.angularDampingRatio = def.angularDampingRatio;\n joint.weldJoint.linearImpulse = new b2Vec2(0, 0);\n joint.weldJoint.angularImpulse = 0.0;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\n/**\n * @function b2CreateWheelJoint\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @param {b2WheelJointDef} def - The wheel joint definition containing configuration parameters\n * @returns {b2JointId} The identifier of the created wheel joint\n * @description\n * Creates a wheel joint between two bodies in a Box2D world. A wheel joint provides two degrees of\n * freedom: translation along a specified axis and rotation about an orthogonal axis. The joint can\n * be configured with a spring and damper mechanism, translation limits, and a motor.\n * @throws {Error} Throws an assertion error if the world is locked\n * @note If collideConnected is false, any contacts between the connected bodies are destroyed\n */\nexport function b2CreateWheelJoint(worldId, def)\n{\n // b2CheckDef(def);\n const world = b2GetWorldFromId(worldId);\n\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2JointId();\n }\n\n const bodyA = b2GetBodyFullId(world, def.bodyIdA);\n const bodyB = b2GetBodyFullId(world, def.bodyIdB);\n\n const pair = b2CreateJoint(world, bodyA, bodyB, def.userData, 1.0, b2JointType.b2_wheelJoint, def.collideConnected);\n\n const joint = pair.jointSim;\n joint.type = b2JointType.b2_wheelJoint;\n joint.localOriginAnchorA = def.localAnchorA;\n joint.localOriginAnchorB = def.localAnchorB;\n\n joint.wheelJoint = new b2WheelJoint();\n joint.wheelJoint.localAxisA = b2Normalize(def.localAxisA);\n joint.wheelJoint.perpMass = 0.0;\n joint.wheelJoint.axialMass = 0.0;\n joint.wheelJoint.motorImpulse = 0.0;\n joint.wheelJoint.lowerImpulse = 0.0;\n joint.wheelJoint.upperImpulse = 0.0;\n joint.wheelJoint.lowerTranslation = def.lowerTranslation;\n joint.wheelJoint.upperTranslation = def.upperTranslation;\n joint.wheelJoint.maxMotorTorque = def.maxMotorTorque;\n joint.wheelJoint.motorSpeed = def.motorSpeed;\n joint.wheelJoint.hertz = def.hertz;\n joint.wheelJoint.dampingRatio = def.dampingRatio;\n joint.wheelJoint.enableSpring = def.enableSpring;\n joint.wheelJoint.enableLimit = def.enableLimit;\n joint.wheelJoint.enableMotor = def.enableMotor;\n\n if (def.collideConnected === false)\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n\n const jointId = new b2JointId(joint.jointId + 1, world.worldId, pair.joint.revision);\n\n return jointId;\n}\n\nexport function b2DestroyJointInternal(world, joint, wakeBodies)\n{\n const jointId = joint.jointId;\n\n const edgeA = joint.edges[0];\n const edgeB = joint.edges[1];\n\n const idA = edgeA.bodyId;\n const idB = edgeB.bodyId;\n const bodyA = b2GetBody(world, idA);\n const bodyB = b2GetBody(world, idB);\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeA.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeA.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const edgeKeyA = (jointId << 1) | 0;\n\n if (bodyA.headJointKey === edgeKeyA)\n {\n bodyA.headJointKey = edgeA.nextKey;\n }\n\n bodyA.jointCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevJoint = world.jointArray[edgeB.prevKey >> 1];\n const prevEdge = prevJoint.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextJoint = world.jointArray[edgeB.nextKey >> 1];\n const nextEdge = nextJoint.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (jointId << 1) | 1;\n\n if (bodyB.headJointKey === edgeKeyB)\n {\n bodyB.headJointKey = edgeB.nextKey;\n }\n\n bodyB.jointCount -= 1;\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Remove joint from solver set that owns it\n const setIndex = joint.setIndex;\n const localIndex = joint.localIndex;\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n b2RemoveJointFromGraph(world, joint.edges[0].bodyId, joint.edges[1].bodyId, joint.colorIndex, localIndex);\n }\n else\n {\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveJoint(set.joints, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved joint\n const movedJointSim = set.joints.data[localIndex];\n const movedId = movedJointSim.jointId;\n const movedJoint = world.jointArray[movedId];\n console.assert(movedJoint.localIndex === movedIndex);\n movedJoint.localIndex = localIndex;\n }\n }\n\n // Free joint and id (preserve joint revision)\n joint.setIndex = B2_NULL_INDEX;\n joint.colorIndex = B2_NULL_INDEX;\n joint.localIndex = B2_NULL_INDEX;\n joint.jointId = B2_NULL_INDEX;\n joint.type = b2JointType.b2_unknown;\n b2FreeId(world.jointIdPool, jointId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2DestroyJoint\n * @param {b2JointId} jointId - The identifier of the joint to be destroyed\n * @returns {void}\n * @description\n * Destroys a joint in the physics world. If the world is locked (e.g. during collision detection\n * or integration), the function will return without destroying the joint. The function internally\n * calls b2DestroyJointInternal to handle the actual joint destruction.\n * @throws {Error} Throws an assertion error if attempting to destroy a joint in a locked world\n */\nexport function b2DestroyJoint(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n b2DestroyJointInternal(world, joint, true);\n}\n\n\n/**\n * Get the world that owns this joint\n * @function b2Chain_GetSegments\n * @param {b2JointId} jointId - The identifier for the joint\n * @returns {b2WorldId}\n */\nexport function b2Joint_GetWorld(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n\n return new b2WorldId(jointId.world0 + 1, world.revision);\n}\n\n\n/**\n * Gets the type of a joint from its ID.\n * @function b2Joint_GetType\n * @param {b2JointId} jointId - The ID of the joint to query.\n * @returns {b2JointType} The type of the specified joint.\n * @description\n * Retrieves the joint type from the world using the provided joint ID.\n * The function first gets the world reference from the joint ID,\n * then retrieves the full joint object to access its type property.\n */\nexport function b2Joint_GetType(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.type;\n}\n\n/**\n * @summary Gets the first body connected to a joint.\n * @function b2Joint_GetBodyA\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of the first body connected to the joint.\n * @description\n * This function retrieves the identifier of the first body (body A) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[0].bodyId);\n}\n\n/**\n * @summary Gets the second body (body B) connected to a joint.\n * @function b2Joint_GetBodyB\n * @param {b2JointId} jointId - The identifier of the joint.\n * @returns {b2BodyId} The identifier of body B connected to the joint.\n * @description\n * This function retrieves the identifier of the second body (body B) that is\n * connected to the specified joint. The joint must exist in the world referenced\n * by the jointId.\n */\nexport function b2Joint_GetBodyB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return b2MakeBodyId(world, joint.edges[1].bodyId);\n}\n\n/**\n * @function b2Joint_GetLocalAnchorA\n * @summary Gets the local anchor point A of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point A in the body A frame.\n * @description\n * Retrieves the local anchor point A from a joint's simulation data. The anchor point\n * is expressed in the local coordinate system of body A.\n */\nexport function b2Joint_GetLocalAnchorA(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorA;\n}\n\n/**\n * @function b2Joint_GetLocalAnchorB\n * @summary Gets the local anchor point B of a joint.\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The local anchor point B in the body's local coordinates.\n * @description\n * Retrieves the local anchor point B of a joint, which represents the connection\n * point on the second body (body B) in that body's local coordinate system.\n */\nexport function b2Joint_GetLocalAnchorB(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const jointSim = b2GetJointSim(world, joint);\n\n return jointSim.localOriginAnchorB;\n}\n\n/**\n * Sets whether two bodies connected by a joint should collide with each other.\n * @function b2Joint_SetCollideConnected\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {boolean} shouldCollide - True to enable collision between connected bodies, false to disable.\n * @returns {void}\n * @description\n * When enabled, the bodies connected by the joint can collide with each other.\n * When disabled, collisions between the connected bodies are filtered out.\n * The function updates the broadphase when enabling collisions and destroys\n * existing contacts between the bodies when disabling collisions.\n */\nexport function b2Joint_SetCollideConnected(jointId, shouldCollide)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n\n if (joint.collideConnected === shouldCollide)\n {\n return;\n }\n\n joint.collideConnected = shouldCollide;\n\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (shouldCollide)\n {\n // need to tell the broad-phase to look for new pairs for one of the\n // two bodies. Pick the one with the fewest shapes.\n const shapeCountA = bodyA.shapeCount;\n const shapeCountB = bodyB.shapeCount;\n\n let shapeId = shapeCountA < shapeCountB ? bodyA.headShapeId : bodyB.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BufferMove(world.broadPhase, shape.proxyKey);\n }\n\n shapeId = shape.nextShapeId;\n }\n }\n else\n {\n b2DestroyContactsBetweenBodies(world, bodyA, bodyB);\n }\n}\n\n/**\n * @function b2Joint_GetCollideConnected\n * @param {b2JointId} jointId - The ID of the joint to query\n * @returns {boolean} Whether the connected bodies can collide with each other\n * @description\n * Gets the collideConnected flag for the specified joint. This flag determines if\n * the two bodies connected by this joint are allowed to collide with each other.\n */\nexport function b2Joint_GetCollideConnected(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.collideConnected;\n}\n\n/**\n * @summary Sets the user data for a joint.\n * @function b2Joint_SetUserData\n * @param {b2JointId} jointId - The identifier for the joint to modify.\n * @param {*} userData - The user data to associate with the joint.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a specified joint in the physics world.\n * The joint is located using its world and joint identifiers, and its user data\n * property is updated with the provided value.\n */\nexport function b2Joint_SetUserData(jointId, userData)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n joint.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a joint.\n * @function b2Joint_GetUserData\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {void} The user data associated with the joint.\n * @description\n * Retrieves the user data that was previously attached to the specified joint.\n * The function first gets the world object from the joint ID, then retrieves\n * the joint using the full joint ID, and finally returns the userData property\n * of that joint.\n */\nexport function b2Joint_GetUserData(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n\n return joint.userData;\n}\n\n/**\n * @function b2Joint_WakeBodies\n * @description\n * Wakes up both bodies connected by a joint in the physics simulation.\n * @param {b2JointId} jointId - The identifier for the joint whose connected bodies should be awakened.\n * @returns {void}\n * @throws {Error} If the world reference in the jointId is invalid or cannot be accessed.\n */\nexport function b2Joint_WakeBodies(jointId)\n{\n const world = b2GetWorldLocked(jointId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const joint = b2GetJointFullId(world, jointId);\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetDistanceJointForce(world, base) {}\n// export function b2GetMotorJointForce(world, base) {}\n// export function b2GetMouseJointForce(world, base) {}\n// export function b2GetPrismaticJointForce(world, base) {}\n// export function b2GetRevoluteJointForce(world, base) {}\n// export function b2GetWeldJointForce(world, base) {}\n// export function b2GetWheelJointForce(world, base) {}\n\n/**\n * Gets the constraint force for a joint.\n * @function b2Joint_GetConstraintForce\n * @param {b2JointId} jointId - The identifier for the joint.\n * @returns {b2Vec2} The constraint force vector. Returns (0,0) for unknown joint types.\n * @description\n * Returns the constraint force for different joint types including distance, motor,\n * mouse, prismatic, revolute, weld, and wheel joints. The force is retrieved from\n * the corresponding joint-specific force getter function.\n * @throws {Error} Throws an assertion error for unknown joint types.\n */\nexport function b2Joint_GetConstraintForce(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return b2GetDistanceJointForce(world, base);\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointForce(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointForce(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointForce(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointForce(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointForce(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointForce(world, base);\n\n default:\n console.assert(false);\n\n return new b2Vec2(0, 0);\n }\n}\n\n// External function declarations (these would be implemented elsewhere)\n// export function b2GetMotorJointTorque(world, base) {}\n// export function b2GetMouseJointTorque(world, base) {}\n// export function b2GetPrismaticJointTorque(world, base) {}\n// export function b2GetRevoluteJointTorque(world, base) {}\n// export function b2GetWeldJointTorque(world, base) {}\n// export function b2GetWheelJointTorque(world, base) {}\n\n/**\n * @function b2Joint_GetConstraintTorque\n * @summary Gets the constraint torque for a joint.\n * @param {b2JointId} jointId - The ID of the joint to get the constraint torque from.\n * @returns {number} The constraint torque value. Returns 0 for distance joints or if joint type is invalid.\n * @description\n * Returns the constraint torque for different joint types including motor, mouse, prismatic,\n * revolute, weld and wheel joints. For distance joints, it always returns 0.\n * @throws {Error} Throws an assertion error if an unsupported joint type is provided.\n */\nexport function b2Joint_GetConstraintTorque(jointId)\n{\n const world = b2GetWorld(jointId.world0);\n const joint = b2GetJointFullId(world, jointId);\n const base = b2GetJointSim(world, joint);\n\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n return 0.0;\n\n case b2JointType.b2_motorJoint:\n return b2GetMotorJointTorque(world, base);\n\n case b2JointType.b2_mouseJoint:\n return b2GetMouseJointTorque(world, base);\n\n case b2JointType.b2_prismaticJoint:\n return b2GetPrismaticJointTorque(world, base);\n\n case b2JointType.b2_revoluteJoint:\n return b2GetRevoluteJointTorque(world, base);\n\n case b2JointType.b2_weldJoint:\n return b2GetWeldJointTorque(world, base);\n\n case b2JointType.b2_wheelJoint:\n return b2GetWheelJointTorque(world, base);\n\n default:\n console.assert(false);\n\n return 0.0;\n }\n}\n\nexport function b2PrepareJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2PrepareDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2PrepareMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2PrepareMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2PreparePrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2PrepareRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2PrepareWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2PrepareWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2WarmStartJoint(joint, context)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2WarmStartDistanceJoint(joint, context);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2WarmStartMotorJoint(joint, context);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2WarmStartMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2WarmStartPrismaticJoint(joint, context);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2WarmStartRevoluteJoint(joint, context);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2WarmStartWeldJoint(joint, context);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2WarmStartWheelJoint(joint, context);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2SolveJoint(joint, context, useBias)\n{\n switch (joint.type)\n {\n case b2JointType.b2_distanceJoint:\n b2SolveDistanceJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_motorJoint:\n b2SolveMotorJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n b2SolveMouseJoint(joint, context);\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2SolvePrismaticJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2SolveRevoluteJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_weldJoint:\n b2SolveWeldJoint(joint, context, useBias);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2SolveWheelJoint(joint, context, useBias);\n\n break;\n\n default:\n console.assert(false);\n }\n}\n\nexport function b2PrepareOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2PrepareJoint(joint, context);\n }\n}\n\nexport function b2WarmStartOverflowJoints(context)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2WarmStartJoint(joint, context);\n }\n}\n\nexport function b2SolveOverflowJoints(context, useBias)\n{\n const graph = context.graph;\n const joints = graph.colors[b2_overflowIndex].joints.data;\n const jointCount = graph.colors[b2_overflowIndex].joints.count;\n\n for (let i = 0; i < jointCount; ++i)\n {\n const joint = joints[i];\n b2SolveJoint(joint, context, useBias);\n }\n}\n\nexport function b2DrawJoint(draw, world, joint)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim);\n\n const transformA = b2GetBodyTransformQuick(world, bodyA);\n const transformB = b2GetBodyTransformQuick(world, bodyB);\n const pA = b2TransformPoint(transformA, jointSim.localOriginAnchorA);\n const pB = b2TransformPoint(transformB, jointSim.localOriginAnchorB);\n\n const color = b2HexColor.b2_colorDarkSeaGreen;\n\n switch (joint.type)\n {\n \n case b2JointType.b2_distanceJoint:\n b2DrawDistanceJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_mouseJoint:\n {\n const target = jointSim.mouseJoint.targetA;\n\n const c1 = b2HexColor.b2_colorGreen;\n draw.DrawPoint(target.x, target.y, 4.0, c1, draw.context);\n draw.DrawPoint(pB.x, pB.y, 4.0, c1, draw.context);\n\n const c2 = b2HexColor.b2_colorGray8;\n draw.DrawSegment(target, pB, c2, draw.context);\n }\n\n break;\n\n case b2JointType.b2_prismaticJoint:\n b2DrawPrismaticJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n case b2JointType.b2_revoluteJoint:\n b2DrawRevoluteJoint(draw, jointSim, transformA, transformB, joint.drawSize);\n\n break;\n\n case b2JointType.b2_wheelJoint:\n b2DrawWheelJoint(draw, jointSim, transformA, transformB);\n\n break;\n\n default:\n draw.DrawSegment(transformA.p, pA, color, draw.context);\n draw.DrawSegment(pA, pB, color, draw.context);\n draw.DrawSegment(transformB.p, pB, color, draw.context);\n }\n\n if (draw.drawGraphColors)\n {\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const colorIndex = joint.colorIndex;\n\n if (colorIndex !== B2_NULL_INDEX)\n {\n const p = b2Lerp(pA, pB, 0.5);\n draw.DrawPoint(p.x, p.y, 5.0, colors[colorIndex], draw.context);\n }\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Mat22, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from './core_h.js';\nimport { b2JointType } from './types_h.js';\nimport { b2Softness } from './solver_h.js';\n\nexport class b2JointEdge\n{\n constructor()\n {\n this.bodyId = B2_NULL_INDEX;\n this.prevKey = B2_NULL_INDEX;\n this.nextKey = B2_NULL_INDEX;\n }\n}\n\nexport class b2Joint\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = B2_NULL_INDEX;\n this.colorIndex = B2_NULL_INDEX;\n this.localIndex = B2_NULL_INDEX;\n this.edges = [ new b2JointEdge(), new b2JointEdge() ];\n this.jointId = B2_NULL_INDEX;\n this.islandId = B2_NULL_INDEX;\n this.islandPrev = B2_NULL_INDEX;\n this.islandNext = B2_NULL_INDEX;\n this.revision = 0;\n this.drawSize = 0;\n this.type = b2JointType.b2_unknown;\n this.isMarked = false;\n this.collideConnected = false;\n }\n}\n\nexport class b2DistanceJoint\n{\n constructor()\n {\n this.length = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.minLength = 0;\n this.maxLength = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.impulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.motorImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.distanceSoftness = new b2Softness();\n this.axialMass = 0;\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const dj = new b2DistanceJoint();\n dj.length = this.length;\n dj.hertz = this.hertz;\n dj.dampingRatio = this.dampingRatio;\n dj.minLength = this.minLength;\n dj.maxLength = this.maxLength;\n dj.maxMotorForce = this.maxMotorForce;\n dj.motorSpeed = this.motorSpeed;\n dj.impulse = this.impulse;\n dj.lowerImpulse = this.lowerImpulse;\n dj.upperImpulse = this.upperImpulse;\n dj.motorImpulse = this.motorImpulse;\n dj.indexA = this.indexA;\n dj.indexB = this.indexB;\n dj.anchorA = this.anchorA.clone();\n dj.anchorB = this.anchorB.clone();\n dj.deltaCenter = this.deltaCenter.clone();\n dj.distanceSoftness = this.distanceSoftness; // this.distanceSoftness.clone(); PJB it's all primitives, we might get away with a reference copy here\n dj.axialMass = this.axialMass;\n dj.enableSpring = this.enableSpring;\n dj.enableLimit = this.enableLimit;\n dj.enableMotor = this.enableMotor;\n\n return dj;\n }\n}\n\nexport class b2MotorJoint\n{\n constructor()\n {\n this.linearOffset = new b2Vec2();\n this.angularOffset = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.maxForce = 0;\n this.maxTorque = 0;\n this.correctionFactor = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.linearMass = new b2Mat22();\n this.angularMass = 0;\n }\n\n clone()\n {\n const mj = new b2MotorJoint();\n mj.linearOffset = this.linearOffset.clone();\n mj.angularOffset = this.angularOffset;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.maxForce = this.maxForce;\n mj.maxTorque = this.maxTorque;\n mj.correctionFactor = this.correctionFactor;\n mj.indexA = this.indexA;\n mj.indexB = this.indexB;\n mj.anchorA = this.anchorA.clone();\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.deltaAngle = this.deltaAngle;\n mj.linearMass = this.linearMass.clone();\n mj.angularMass = this.angularMass;\n\n return mj;\n }\n}\n\nexport class b2MouseJoint\n{\n constructor()\n {\n this.targetA = new b2Vec2();\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxForce = 0;\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.indexB = B2_NULL_INDEX;\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.linearMass = new b2Mat22();\n }\n\n clone()\n {\n const mj = new b2MouseJoint();\n mj.targetA = this.targetA.clone();\n mj.hertz = this.hertz;\n mj.dampingRatio = this.dampingRatio;\n mj.maxForce = this.maxForce;\n mj.linearImpulse = this.linearImpulse.clone();\n mj.angularImpulse = this.angularImpulse;\n mj.linearSoftness = this.linearSoftness;\n mj.angularSoftness = this.angularSoftness;\n mj.indexB = this.indexB;\n mj.anchorB = this.anchorB.clone();\n mj.deltaCenter = this.deltaCenter.clone();\n mj.linearMass = this.linearMass.clone();\n\n return mj;\n }\n}\n\nexport class b2PrismaticJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.impulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorForce = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableLimit = false;\n this.enableMotor = false;\n }\n\n clone()\n {\n const pj = new b2PrismaticJoint();\n pj.localAxisA = this.localAxisA.clone();\n pj.impulse = this.impulse.clone();\n pj.springImpulse = this.springImpulse;\n pj.motorImpulse = this.motorImpulse;\n pj.lowerImpulse = this.lowerImpulse;\n pj.upperImpulse = this.upperImpulse;\n pj.hertz = this.hertz;\n pj.dampingRatio = this.dampingRatio;\n pj.maxMotorForce = this.maxMotorForce;\n pj.motorSpeed = this.motorSpeed;\n pj.referenceAngle = this.referenceAngle;\n pj.lowerTranslation = this.lowerTranslation;\n pj.upperTranslation = this.upperTranslation;\n pj.indexA = this.indexA;\n pj.indexB = this.indexB;\n pj.anchorA = this.anchorA.clone();\n pj.anchorB = this.anchorB.clone();\n pj.axisA = this.axisA.clone();\n pj.deltaCenter = this.deltaCenter.clone();\n pj.deltaAngle = this.deltaAngle;\n pj.axialMass = this.axialMass;\n pj.springSoftness = this.springSoftness.clone();\n pj.enableSpring = this.enableSpring;\n pj.enableLimit = this.enableLimit;\n pj.enableMotor = this.enableMotor;\n\n return pj;\n }\n}\n\nexport class b2RevoluteJoint\n{\n constructor()\n {\n this.linearImpulse = new b2Vec2();\n this.springImpulse = 0;\n this.motorImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.referenceAngle = 0;\n this.lowerAngle = 0;\n this.upperAngle = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const rj = new b2RevoluteJoint();\n rj.linearImpulse = this.linearImpulse.clone();\n rj.springImpulse = this.springImpulse;\n rj.motorImpulse = this.motorImpulse;\n rj.lowerImpulse = this.lowerImpulse;\n rj.upperImpulse = this.upperImpulse;\n rj.hertz = this.hertz;\n rj.dampingRatio = this.dampingRatio;\n rj.maxMotorTorque = this.maxMotorTorque;\n rj.motorSpeed = this.motorSpeed;\n rj.referenceAngle = this.referenceAngle;\n rj.lowerAngle = this.lowerAngle;\n rj.upperAngle = this.upperAngle;\n rj.indexA = this.indexA;\n rj.indexB = this.indexB;\n rj.anchorA = this.anchorA.clone();\n rj.anchorB = this.anchorB.clone();\n rj.deltaCenter = this.deltaCenter.clone();\n rj.deltaAngle = this.deltaAngle;\n rj.axialMass = this.axialMass;\n rj.springSoftness = this.springSoftness;\n rj.enableSpring = this.enableSpring;\n rj.enableMotor = this.enableMotor;\n rj.enableLimit = this.enableLimit;\n\n return rj;\n }\n}\n\nexport class b2WeldJoint\n{\n constructor()\n {\n this.referenceAngle = 0;\n this.linearHertz = 0;\n this.linearDampingRatio = 0;\n this.angularHertz = 0;\n this.angularDampingRatio = 0;\n this.linearSoftness = new b2Softness();\n this.angularSoftness = new b2Softness();\n this.linearImpulse = new b2Vec2();\n this.angularImpulse = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.deltaAngle = 0;\n this.axialMass = 0;\n }\n\n clone()\n {\n const wj = new b2WeldJoint();\n wj.referenceAngle = this.referenceAngle;\n wj.linearHertz = this.linearHertz;\n wj.linearDampingRatio = this.linearDampingRatio;\n wj.angularHertz = this.angularHertz;\n wj.angularDampingRatio = this.angularDampingRatio;\n wj.linearSoftness = this.linearSoftness;\n wj.angularSoftness = this.angularSoftness;\n wj.linearImpulse = this.linearImpulse.clone();\n wj.angularImpulse = this.angularImpulse;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.deltaAngle = this.deltaAngle;\n wj.axialMass = this.axialMass;\n\n return wj;\n }\n}\n\nexport class b2WheelJoint\n{\n constructor()\n {\n this.localAxisA = new b2Vec2();\n this.perpImpulse = 0;\n this.motorImpulse = 0;\n this.springImpulse = 0;\n this.lowerImpulse = 0;\n this.upperImpulse = 0;\n this.maxMotorTorque = 0;\n this.motorSpeed = 0;\n this.lowerTranslation = 0;\n this.upperTranslation = 0;\n this.hertz = 0;\n this.dampingRatio = 0;\n this.indexA = B2_NULL_INDEX;\n this.indexB = B2_NULL_INDEX;\n this.anchorA = new b2Vec2();\n this.anchorB = new b2Vec2();\n this.axisA = new b2Vec2();\n this.deltaCenter = new b2Vec2();\n this.perpMass = 0;\n this.motorMass = 0;\n this.axialMass = 0;\n this.springSoftness = new b2Softness();\n this.enableSpring = false;\n this.enableMotor = false;\n this.enableLimit = false;\n }\n\n clone()\n {\n const wj = new b2WheelJoint();\n wj.localAxisA = this.localAxisA.clone();\n wj.perpImpulse = this.perpImpulse;\n wj.motorImpulse = this.motorImpulse;\n wj.springImpulse = this.springImpulse;\n wj.lowerImpulse = this.lowerImpulse;\n wj.upperImpulse = this.upperImpulse;\n wj.maxMotorTorque = this.maxMotorTorque;\n wj.motorSpeed = this.motorSpeed;\n wj.lowerTranslation = this.lowerTranslation;\n wj.upperTranslation = this.upperTranslation;\n wj.hertz = this.hertz;\n wj.dampingRatio = this.dampingRatio;\n wj.indexA = this.indexA;\n wj.indexB = this.indexB;\n wj.anchorA = this.anchorA.clone();\n wj.anchorB = this.anchorB.clone();\n wj.axisA = this.axisA.clone();\n wj.deltaCenter = this.deltaCenter.clone();\n wj.perpMass = this.perpMass;\n wj.motorMass = this.motorMass;\n wj.axialMass = this.axialMass;\n wj.springSoftness = this.springSoftness;\n wj.enableSpring = this.enableSpring;\n wj.enableMotor = this.enableMotor;\n wj.enableLimit = this.enableLimit;\n\n return wj;\n }\n}\n\nexport class b2JointSim\n{\n constructor()\n {\n this.jointId = B2_NULL_INDEX;\n this.bodyIdA = B2_NULL_INDEX;\n this.bodyIdB = B2_NULL_INDEX;\n this.type = b2JointType.b2_unknown;\n this.localOriginAnchorA = new b2Vec2();\n this.localOriginAnchorB = new b2Vec2();\n this.invMassA = 0;\n this.invMassB = 0;\n this.invIA = 0;\n this.invIB = 0;\n this.joint = null;\n\n // in C these joints are in a union\n // (shouldn't matter that they're separate here, unless there's any sneaky type swapping being done)\n this.distanceJoint = null;\n this.motorJoint = null;\n this.mouseJoint = null;\n this.revoluteJoint = null;\n this.prismaticJoint = null;\n this.weldJoint = null;\n this.wheelJoint = null;\n }\n\n copyTo(dst)\n {\n dst.jointId = this.jointId;\n dst.bodyIdA = this.bodyIdA;\n dst.bodyIdB = this.bodyIdB;\n dst.type = this.type;\n dst.localOriginAnchorA = this.localOriginAnchorA.clone();\n dst.localOriginAnchorB = this.localOriginAnchorB.clone();\n dst.invMassA = this.invMassA;\n dst.invMassB = this.invMassB;\n dst.invIA = this.invIA;\n dst.invIB = this.invIB;\n dst.joint = this.joint;\n dst.distanceJoint = (this.distanceJoint ? this.distanceJoint.clone() : null);\n dst.motorJoint = (this.motorJoint ? this.motorJoint.clone() : null);\n dst.mouseJoint = (this.mouseJoint ? this.mouseJoint.clone() : null);\n dst.revoluteJoint = (this.revoluteJoint ? this.revoluteJoint.clone() : null);\n dst.prismaticJoint = (this.prismaticJoint ? this.prismaticJoint.clone() : null);\n dst.weldJoint = (this.weldJoint ? this.weldJoint.clone() : null);\n dst.wheelJoint = (this.wheelJoint ? this.wheelJoint.clone() : null);\n }\n}\n\nexport {\n b2GetJoint, b2DestroyJointInternal, b2DestroyJoint, b2PrepareJoint, b2WarmStartJoint, b2SolveJoint, b2DrawJoint,\n b2GetJointSim, b2GetJointSimCheckType,\n b2PrepareOverflowJoints, b2WarmStartOverflowJoints, b2SolveOverflowJoints,\n b2CreateRevoluteJoint, b2CreateWheelJoint, b2CreateWeldJoint, b2CreatePrismaticJoint, b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint,\n b2Joint_GetWorld,\n b2Joint_WakeBodies, b2Joint_GetBodyA, b2Joint_GetBodyB, b2Joint_GetCollideConnected, b2Joint_GetConstraintForce, b2Joint_GetConstraintTorque, b2Joint_GetLocalAnchorA, b2Joint_GetLocalAnchorB,\n b2Joint_GetType, b2Joint_GetUserData, b2Joint_SetUserData, b2Joint_SetCollideConnected,\n b2DefaultDistanceJointDef,b2DefaultMotorJointDef,b2DefaultMouseJointDef,b2DefaultPrismaticJointDef,b2DefaultRevoluteJointDef,b2DefaultWeldJointDef,b2DefaultWheelJointDef\n} from '../joint_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AddIsland, b2RemoveIsland } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2CheckIndex, b2SetType, b2ValidateConnectivity } from './include/world_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactFlags } from './include/contact_h.js';\nimport { b2GetBody } from './include/body_h.js';\nimport { b2GetJoint } from './include/joint_h.js';\nimport { b2Validation } from './include/types_h.js';\nimport { b2WakeSolverSet } from './include/solver_set_h.js';\n\n/**\n * @namespace Island\n */\n\n// Persistent island for awake bodies, joints, and contacts\n// https://en.wikipedia.org/wiki/Component_(graph_theory)\n// https://en.wikipedia.org/wiki/Dynamic_connectivity\n// map from int to solver set and index\nexport class b2Island\n{\n setIndex = 0;\n localIndex = 0;\n islandId = 0;\n headBody = 0;\n tailBody = 0;\n bodyCount = 0;\n headContact = 0;\n tailContact = 0;\n contactCount = 0;\n headJoint = 0;\n tailJoint = 0;\n jointCount = 0;\n parentIsland = 0;\n constraintRemoveCount = 0;\n}\n\nexport class b2IslandSim\n{\n islandId = 0;\n}\n\nexport function b2CreateIsland(world, setIndex)\n{\n console.assert(setIndex === b2SetType.b2_awakeSet || setIndex >= b2SetType.b2_firstSleepingSet);\n\n const islandId = b2AllocId(world.islandIdPool);\n\n if (islandId === world.islandArray.length)\n {\n const emptyIsland = new b2Island();\n emptyIsland.setIndex = B2_NULL_INDEX; // { setIndex: B2_NULL_INDEX };\n world.islandArray.push(emptyIsland);\n }\n else\n {\n console.assert(world.islandArray[islandId].setIndex === B2_NULL_INDEX);\n }\n\n // b2CheckIndex(world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n\n const island = world.islandArray[islandId];\n island.setIndex = setIndex;\n island.localIndex = set.islands.count;\n island.islandId = islandId;\n island.headBody = B2_NULL_INDEX;\n island.tailBody = B2_NULL_INDEX;\n island.bodyCount = 0;\n island.headContact = B2_NULL_INDEX;\n island.tailContact = B2_NULL_INDEX;\n island.contactCount = 0;\n island.headJoint = B2_NULL_INDEX;\n island.tailJoint = B2_NULL_INDEX;\n island.jointCount = 0;\n island.parentIsland = B2_NULL_INDEX;\n island.constraintRemoveCount = 0;\n\n const islandSim = b2AddIsland(set.islands);\n islandSim.islandId = islandId;\n\n return island;\n}\n\nexport function b2DestroyIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // b2CheckIndex(world.solverSetArray, island.setIndex);\n const set = world.solverSetArray[island.setIndex];\n const movedIndex = b2RemoveIsland(set.islands, island.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedElement = set.islands.data[island.localIndex];\n const movedId = movedElement.islandId;\n const movedIsland = world.islandArray[movedId];\n console.assert(movedIsland.localIndex === movedIndex);\n movedIsland.localIndex = island.localIndex;\n }\n\n island.islandId = B2_NULL_INDEX;\n island.setIndex = B2_NULL_INDEX;\n island.localIndex = B2_NULL_INDEX;\n b2FreeId(world.islandIdPool, islandId);\n}\n\nexport function b2GetIsland(world, islandId)\n{\n // b2CheckIndex(world.islandArray, islandId);\n return world.islandArray[islandId];\n}\n\nfunction b2AddContactToIsland(world, islandId, contact)\n{\n console.assert(contact.islandId === B2_NULL_INDEX);\n console.assert(contact.islandPrev === B2_NULL_INDEX);\n console.assert(contact.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headContact !== B2_NULL_INDEX)\n {\n contact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n headContact.islandPrev = contact.contactId;\n }\n\n island.headContact = contact.contactId;\n\n if (island.tailContact === B2_NULL_INDEX)\n {\n island.tailContact = island.headContact;\n }\n\n island.contactCount += 1;\n contact.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0 && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n console.assert(bodyA.setIndex !== b2SetType.b2_disabledSet && bodyB.setIndex !== b2SetType.b2_disabledSet);\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || bodyB.setIndex !== b2SetType.b2_staticSet);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n\n if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(bodyA.setIndex !== b2SetType.b2_staticSet || islandIdA === B2_NULL_INDEX);\n console.assert(bodyB.setIndex !== b2SetType.b2_staticSet || islandIdB === B2_NULL_INDEX);\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n let parentId = islandA.parentIsland;\n\n while (parentId !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandA = parent;\n islandIdA = parentId;\n parentId = islandA.parentIsland;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n let parentId = islandB.parentIsland;\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, parentId);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandB = parent;\n islandIdB = parentId;\n parentId = islandB.parentIsland;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddContactToIsland(world, islandIdA, contact);\n }\n else\n {\n b2AddContactToIsland(world, islandIdB, contact);\n }\n}\n\nexport function b2UnlinkContact(world, contact)\n{\n console.assert((contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0);\n console.assert(contact.islandId !== B2_NULL_INDEX);\n\n const islandId = contact.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = b2GetIsland(world, islandId);\n\n if (contact.islandPrev !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandPrev);\n const prevContact = world.contactArray[contact.islandPrev];\n console.assert(prevContact.islandNext === contact.contactId);\n prevContact.islandNext = contact.islandNext;\n }\n\n if (contact.islandNext !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contact.islandNext);\n const nextContact = world.contactArray[contact.islandNext];\n console.assert(nextContact.islandPrev === contact.contactId);\n nextContact.islandPrev = contact.islandPrev;\n }\n\n if (island.headContact === contact.contactId)\n {\n island.headContact = contact.islandNext;\n }\n\n if (island.tailContact === contact.contactId)\n {\n island.tailContact = contact.islandPrev;\n }\n\n console.assert(island.contactCount > 0);\n island.contactCount -= 1;\n island.constraintRemoveCount += 1;\n\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2AddJointToIsland(world, islandId, joint)\n{\n console.assert(joint.islandId === B2_NULL_INDEX);\n console.assert(joint.islandPrev === B2_NULL_INDEX);\n console.assert(joint.islandNext === B2_NULL_INDEX);\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (island.headJoint !== B2_NULL_INDEX)\n {\n joint.islandNext = island.headJoint;\n const headJoint = b2GetJoint(world, island.headJoint);\n headJoint.islandPrev = joint.jointId;\n }\n\n island.headJoint = joint.jointId;\n\n if (island.tailJoint === B2_NULL_INDEX)\n {\n island.tailJoint = island.headJoint;\n }\n\n island.jointCount += 1;\n joint.islandId = islandId;\n\n b2ValidateIsland(world, islandId);\n}\n\nexport function b2LinkJoint(world, joint, mergeIslands)\n{\n const bodyA = b2GetBody(world, joint.edges[0].bodyId);\n const bodyB = b2GetBody(world, joint.edges[1].bodyId);\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet && bodyB.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyB.setIndex);\n }\n else if (bodyB.setIndex === b2SetType.b2_awakeSet && bodyA.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, bodyA.setIndex);\n }\n\n let islandIdA = bodyA.islandId;\n let islandIdB = bodyB.islandId;\n\n console.assert(islandIdA !== B2_NULL_INDEX || islandIdB !== B2_NULL_INDEX);\n\n if (islandIdA === islandIdB)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n\n return;\n }\n\n let islandA = null;\n\n if (islandIdA !== B2_NULL_INDEX)\n {\n islandA = b2GetIsland(world, islandIdA);\n\n while (islandA.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandA.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandA.parentIsland = parent.parentIsland;\n }\n\n islandIdA = islandA.parentIsland;\n islandA = parent;\n }\n }\n\n let islandB = null;\n\n if (islandIdB !== B2_NULL_INDEX)\n {\n islandB = b2GetIsland(world, islandIdB);\n\n while (islandB.parentIsland !== B2_NULL_INDEX)\n {\n const parent = b2GetIsland(world, islandB.parentIsland);\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n islandB.parentIsland = parent.parentIsland;\n }\n\n islandIdB = islandB.parentIsland;\n islandB = parent;\n }\n }\n\n console.assert(islandA !== null || islandB !== null);\n\n if (islandA !== islandB && islandA !== null && islandB !== null)\n {\n console.assert(islandA !== islandB);\n console.assert(islandB.parentIsland === B2_NULL_INDEX);\n islandB.parentIsland = islandIdA;\n }\n\n if (islandA !== null)\n {\n b2AddJointToIsland(world, islandIdA, joint);\n }\n else\n {\n b2AddJointToIsland(world, islandIdB, joint);\n }\n\n // Joints need to have islands merged immediately when they are created\n // to keep the island graph valid.\n // However, when a body type is being changed the merge can be deferred until\n // all joints are linked.\n if (mergeIslands)\n {\n b2MergeAwakeIslands(world);\n }\n}\n\nexport function b2UnlinkJoint(world, joint)\n{\n console.assert(joint.islandId !== B2_NULL_INDEX);\n\n const islandId = joint.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n if (joint.islandPrev !== B2_NULL_INDEX)\n {\n const prevJoint = b2GetJoint(world, joint.islandPrev);\n console.assert(prevJoint.islandNext === joint.jointId);\n prevJoint.islandNext = joint.islandNext;\n }\n\n if (joint.islandNext !== B2_NULL_INDEX)\n {\n const nextJoint = b2GetJoint(world, joint.islandNext);\n console.assert(nextJoint.islandPrev === joint.jointId);\n nextJoint.islandPrev = joint.islandPrev;\n }\n\n if (island.headJoint === joint.jointId)\n {\n island.headJoint = joint.islandNext;\n }\n\n if (island.tailJoint === joint.jointId)\n {\n island.tailJoint = joint.islandPrev;\n }\n\n console.assert(island.jointCount > 0);\n island.jointCount -= 1;\n island.constraintRemoveCount += 1;\n\n joint.islandId = B2_NULL_INDEX;\n joint.islandPrev = B2_NULL_INDEX;\n joint.islandNext = B2_NULL_INDEX;\n\n b2ValidateIsland(world, islandId);\n}\n\nfunction b2MergeIsland(world, island)\n{\n console.assert(island.parentIsland !== B2_NULL_INDEX);\n\n const rootId = island.parentIsland;\n\n // b2CheckIndex(world.islandArray, rootId);\n const rootIsland = world.islandArray[rootId];\n console.assert(rootIsland.parentIsland === B2_NULL_INDEX);\n\n let bodyId = island.headBody;\n\n while (bodyId !== B2_NULL_INDEX)\n {\n const body = b2GetBody(world, bodyId);\n body.islandId = rootId;\n bodyId = body.islandNext;\n }\n\n let contactId = island.headContact;\n\n while (contactId !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n contact.islandId = rootId;\n contactId = contact.islandNext;\n }\n\n let jointId = island.headJoint;\n\n while (jointId !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, jointId);\n joint.islandId = rootId;\n jointId = joint.islandNext;\n }\n\n console.assert(rootIsland.tailBody !== B2_NULL_INDEX);\n const tailBody = b2GetBody(world, rootIsland.tailBody);\n console.assert(tailBody.islandNext === B2_NULL_INDEX);\n tailBody.islandNext = island.headBody;\n\n console.assert(island.headBody !== B2_NULL_INDEX);\n const headBody = b2GetBody(world, island.headBody);\n console.assert(headBody.islandPrev === B2_NULL_INDEX);\n headBody.islandPrev = rootIsland.tailBody;\n\n rootIsland.tailBody = island.tailBody;\n rootIsland.bodyCount += island.bodyCount;\n\n if (rootIsland.headContact === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailContact === B2_NULL_INDEX && rootIsland.contactCount === 0);\n rootIsland.headContact = island.headContact;\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount = island.contactCount;\n }\n else if (island.headContact !== B2_NULL_INDEX)\n {\n console.assert(island.tailContact !== B2_NULL_INDEX && island.contactCount > 0);\n console.assert(rootIsland.tailContact !== B2_NULL_INDEX && rootIsland.contactCount > 0);\n\n // b2CheckIndex(world.contactArray, rootIsland.tailContact);\n const tailContact = world.contactArray[rootIsland.tailContact];\n console.assert(tailContact.islandNext === B2_NULL_INDEX);\n tailContact.islandNext = island.headContact;\n\n // b2CheckIndex(world.contactArray, island.headContact);\n const headContact = world.contactArray[island.headContact];\n console.assert(headContact.islandPrev === B2_NULL_INDEX);\n headContact.islandPrev = rootIsland.tailContact;\n\n rootIsland.tailContact = island.tailContact;\n rootIsland.contactCount += island.contactCount;\n }\n\n if (rootIsland.headJoint === B2_NULL_INDEX)\n {\n console.assert(rootIsland.tailJoint === B2_NULL_INDEX && rootIsland.jointCount === 0);\n rootIsland.headJoint = island.headJoint;\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount = island.jointCount;\n }\n else if (island.headJoint !== B2_NULL_INDEX)\n {\n console.assert(island.tailJoint !== B2_NULL_INDEX && island.jointCount > 0);\n console.assert(rootIsland.tailJoint !== B2_NULL_INDEX && rootIsland.jointCount > 0);\n\n const tailJoint = b2GetJoint(world, rootIsland.tailJoint);\n console.assert(tailJoint.islandNext === B2_NULL_INDEX);\n tailJoint.islandNext = island.headJoint;\n\n const headJoint = b2GetJoint(world, island.headJoint);\n console.assert(headJoint.islandPrev === B2_NULL_INDEX);\n headJoint.islandPrev = rootIsland.tailJoint;\n\n rootIsland.tailJoint = island.tailJoint;\n rootIsland.jointCount += island.jointCount;\n }\n\n rootIsland.constraintRemoveCount += island.constraintRemoveCount;\n\n b2ValidateIsland(world, rootId);\n}\n\nexport function b2MergeAwakeIslands(world)\n{\n // b2TracyCZoneNC(\"merge_islands\", \"Merge Islands\", b2HexColor.b2_colorMediumTurquoise, true);\n\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n const islandSims = awakeSet.islands.data;\n const awakeIslandCount = awakeSet.islands.count;\n const islands = world.islandArray;\n\n for (let i = 0; i < awakeIslandCount; ++i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n let rootId = islandId;\n let rootIsland = island;\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n // b2CheckIndex(islands, rootIsland.parentIsland);\n const parent = islands[rootIsland.parentIsland];\n\n if (parent.parentIsland !== B2_NULL_INDEX)\n {\n rootIsland.parentIsland = parent.parentIsland;\n }\n\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n if (rootIsland !== island)\n {\n island.parentIsland = rootId;\n }\n }\n\n for (let i = awakeIslandCount - 1; i >= 0; --i)\n {\n const islandId = islandSims[i].islandId;\n\n // b2CheckIndex(islands, islandId);\n const island = islands[islandId];\n\n if (island.parentIsland === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2MergeIsland(world, island);\n\n b2DestroyIsland(world, islandId);\n }\n\n b2ValidateConnectivity(world);\n\n // b2TracyCZoneEnd(\"merge_islands\");\n}\n\nexport function b2SplitIsland(world, baseId)\n{\n // b2CheckIndex(world.islandArray, baseId);\n const baseIsland = world.islandArray[baseId];\n const setIndex = baseIsland.setIndex;\n\n if (setIndex !== b2SetType.b2_awakeSet)\n {\n // can only split awake island\n return;\n }\n\n if (baseIsland.constraintRemoveCount === 0)\n {\n // this island doesn't need to be split\n return;\n }\n\n b2ValidateIsland(world, baseId);\n\n const bodyCount = baseIsland.bodyCount;\n\n const bodies = world.bodyArray;\n const contacts = world.contactArray;\n\n const stack = [];\n const bodyIds = [];\n\n // Build array containing all body indices from base island. These\n // serve as seed bodies for the depth first search (DFS).\n let nextBody = baseIsland.headBody;\n\n while (nextBody !== B2_NULL_INDEX)\n {\n bodyIds.push(nextBody);\n const body = bodies[nextBody];\n\n // Clear visitation mark\n body.isMarked = false;\n\n nextBody = body.islandNext;\n }\n console.assert(bodyIds.length === bodyCount);\n\n // Clear contact island flags. Only need to consider contacts\n // already in the base island.\n let nextContactId = baseIsland.headContact;\n\n while (nextContactId !== B2_NULL_INDEX)\n {\n const contact = contacts[nextContactId];\n contact.isMarked = false;\n nextContactId = contact.islandNext;\n }\n\n // Clear joint island flags.\n let nextJoint = baseIsland.headJoint;\n\n while (nextJoint !== B2_NULL_INDEX)\n {\n const joint = b2GetJoint(world, nextJoint);\n joint.isMarked = false;\n nextJoint = joint.islandNext;\n }\n\n // Done with the base split island.\n b2DestroyIsland(world, baseId);\n\n // Each island is found as a depth first search starting from a seed body\n for (let i = 0; i < bodyCount; ++i)\n {\n const seedIndex = bodyIds[i];\n const seed = bodies[seedIndex];\n console.assert(seed.setIndex === setIndex);\n\n if (seed.isMarked === true)\n {\n continue;\n }\n\n stack.push(seedIndex);\n seed.isMarked = true;\n\n const island = b2CreateIsland(world, setIndex);\n\n const islandId = island.islandId;\n\n while (stack.length > 0)\n {\n const bodyId = stack.pop();\n const body = bodies[bodyId];\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n console.assert(body.isMarked === true);\n\n body.islandId = islandId;\n\n if (island.tailBody !== B2_NULL_INDEX)\n {\n bodies[island.tailBody].islandNext = bodyId;\n }\n body.islandPrev = island.tailBody;\n body.islandNext = B2_NULL_INDEX;\n island.tailBody = bodyId;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n island.headBody = bodyId;\n }\n\n island.bodyCount += 1;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.contactId === contactId);\n\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.isMarked)\n {\n continue;\n }\n\n if (contact.flags & b2ContactFlags.b2_contactSensorFlag)\n {\n continue;\n }\n\n if ((contact.flags & b2ContactFlags.b2_contactTouchingFlag) === 0)\n {\n continue;\n }\n\n contact.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = contact.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.isMarked === false && otherBody.setIndex !== b2SetType.b2_staticSet)\n {\n console.assert(stack.length < bodyCount);\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n contact.islandId = islandId;\n\n if (island.tailContact !== B2_NULL_INDEX)\n {\n // b2CheckIndex(world.contactArray, island.tailContact);\n const tailContact = world.contactArray[island.tailContact];\n tailContact.islandNext = contactId;\n }\n contact.islandPrev = island.tailContact;\n contact.islandNext = B2_NULL_INDEX;\n island.tailContact = contactId;\n\n if (island.headContact === B2_NULL_INDEX)\n {\n island.headContact = contactId;\n }\n\n island.contactCount += 1;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = b2GetJoint(world, jointId);\n console.assert(joint.jointId === jointId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n if (joint.isMarked)\n {\n continue;\n }\n\n joint.isMarked = true;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n const otherBody = bodies[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (otherBody.isMarked === false && otherBody.setIndex === b2SetType.b2_awakeSet)\n {\n stack.push(otherBodyId);\n otherBody.isMarked = true;\n }\n\n joint.islandId = islandId;\n\n if (island.tailJoint !== B2_NULL_INDEX)\n {\n const tailJoint = b2GetJoint(world, island.tailJoint);\n tailJoint.islandNext = jointId;\n }\n joint.islandPrev = island.tailJoint;\n joint.islandNext = B2_NULL_INDEX;\n island.tailJoint = jointId;\n\n if (island.headJoint === B2_NULL_INDEX)\n {\n island.headJoint = jointId;\n }\n\n island.jointCount += 1;\n }\n }\n\n b2ValidateIsland(world, islandId);\n }\n\n // b2FreeStackItem(alloc, bodyIds);\n // b2FreeStackItem(alloc, stack);\n}\n\nexport function b2ValidateIsland(world, islandId)\n{\n if (!b2Validation) { return; }\n \n b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n console.assert(island.islandId == islandId);\n console.assert(island.setIndex != B2_NULL_INDEX);\n console.assert(island.headBody != B2_NULL_INDEX);\n\n {\n const bodies = world.bodyArray;\n console.assert(island.tailBody != B2_NULL_INDEX);\n console.assert(island.bodyCount > 0);\n\n if (island.bodyCount > 1)\n {\n console.assert(island.tailBody != island.headBody);\n }\n console.assert(island.bodyCount <= b2GetIdCount(world.bodyIdPool));\n\n let count = 0;\n let bodyId = island.headBody;\n\n while (bodyId != B2_NULL_INDEX)\n {\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.islandId == islandId);\n console.assert(body.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.bodyCount)\n {\n console.assert(bodyId == island.tailBody);\n }\n\n bodyId = body.islandNext;\n }\n console.assert(count == island.bodyCount);\n }\n\n if (island.headContact != B2_NULL_INDEX)\n {\n console.assert(island.tailContact != B2_NULL_INDEX);\n console.assert(island.contactCount > 0);\n\n if (island.contactCount > 1)\n {\n console.assert(island.tailContact != island.headContact);\n }\n console.assert(island.contactCount <= b2GetIdCount(world.contactIdPool));\n\n let count = 0;\n let contactId = island.headContact;\n\n while (contactId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex == island.setIndex);\n console.assert(contact.islandId == islandId);\n count += 1;\n\n if (count == island.contactCount)\n {\n console.assert(contactId == island.tailContact);\n }\n\n contactId = contact.islandNext;\n }\n console.assert(count == island.contactCount);\n }\n else\n {\n console.assert(island.tailContact == B2_NULL_INDEX);\n console.assert(island.contactCount == 0);\n }\n\n if (island.headJoint != B2_NULL_INDEX)\n {\n console.assert(island.tailJoint != B2_NULL_INDEX);\n console.assert(island.jointCount > 0);\n\n if (island.jointCount > 1)\n {\n console.assert(island.tailJoint != island.headJoint);\n }\n console.assert(island.jointCount <= b2GetIdCount(world.jointIdPool));\n\n let count = 0;\n let jointId = island.headJoint;\n\n while (jointId != B2_NULL_INDEX)\n {\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex == island.setIndex);\n count += 1;\n\n if (count == island.jointCount)\n {\n console.assert(jointId == island.tailJoint);\n }\n\n jointId = joint.islandNext;\n }\n console.assert(count == island.jointCount);\n }\n else\n {\n console.assert(island.tailJoint == B2_NULL_INDEX);\n console.assert(island.jointCount == 0);\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_HUGE, B2_NULL_INDEX, b2_aabbMargin, b2_graphColorCount, b2_speculativeDistance } from './include/core_h.js';\nimport { b2AABB, b2AABB_Contains, b2AABB_Union, b2Add, b2Cross, b2CrossSV, b2Dot, b2InvRotateVector, b2InvTransformPoint, b2IsValid, b2LengthSquared, b2MulAdd, b2MulSV, b2Rot, b2Rot_IsValid, b2RotateVector, b2Sub, b2Transform, b2TransformPoint, b2Vec2, b2Vec2_IsValid } from './include/math_functions_h.js';\nimport { b2AddBodySim, b2AddBodyState, b2RemoveBodySim, b2RemoveBodyState } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport { b2BodyId, b2JointId, b2ShapeId } from './include/id_h.js';\nimport { b2ComputeShapeAABB, b2ComputeShapeExtent, b2ComputeShapeMass, b2CreateShapeProxy, b2DestroyShapeProxy } from './include/shape_h.js';\nimport { b2ContactFlags, b2DestroyContact, b2GetContactSim } from './include/contact_h.js';\nimport { b2CreateIsland, b2DestroyIsland, b2LinkJoint, b2MergeAwakeIslands, b2SplitIsland, b2UnlinkJoint, b2ValidateIsland } from './include/island_h.js';\nimport { b2DestroyJointInternal, b2GetJoint } from './include/joint_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2TransferBody, b2TransferJoint, b2TrySleepIsland, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2GetWorld, b2GetWorldLocked } from './include/world_h.js';\nimport { b2GetWorldFromId, b2SetType, b2ValidateConnectivity, b2ValidateSolverSets } from './include/world_h.js';\n\nimport { b2Body } from './include/body_h.js';\nimport { b2BodyType } from './include/types_h.js';\nimport { b2Body_IsValid } from './include/world_h.js';\nimport { b2BroadPhase_MoveProxy } from './include/broad_phase_h.js';\nimport { b2MassData } from './include/collision_h.js';\n\n/**\n * @namespace Body\n */\n\nexport function b2MakeSweep(bodySim, out)\n{\n out.c1.x = bodySim.center0X;\n out.c1.y = bodySim.center0Y;\n out.c2.copy(bodySim.center);\n out.q1.copy(bodySim.rotation0);\n out.q2.copy(bodySim.transform.q);\n out.localCenter.copy(bodySim.localCenter);\n\n return out;\n}\n\nexport function b2GetBody(world, bodyId)\n{\n return world.bodyArray[bodyId];\n}\n\nexport function b2GetBodyFullId(world, bodyId)\n{\n console.assert(b2Body_IsValid(bodyId), `invalid bodyId ${JSON.stringify(bodyId)}\\n${new Error().stack}`);\n\n return b2GetBody(world, bodyId.index1 - 1);\n}\n\nexport function b2GetBodyTransformQuick(world, body)\n{\n console.assert(0 <= body.setIndex && body.setIndex < world.solverSetArray.length);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex <= set.sims.count);\n const bodySim = set.sims.data[body.localIndex];\n console.assert(bodySim.transform != null);\n console.assert(bodySim.transform.p != null);\n console.assert(!Number.isNaN(bodySim.transform.p.x));\n console.assert(!Number.isNaN(bodySim.transform.q.c));\n\n return bodySim.transform;\n}\n\nexport function b2GetBodyTransform(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return b2GetBodyTransformQuick(world, body);\n}\n\nexport function b2MakeBodyId(world, bodyId)\n{\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2GetBodySim(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n const set = world.solverSetArray[body.setIndex];\n console.assert(0 <= body.localIndex && body.localIndex < set.sims.count);\n\n return set.sims.data[body.localIndex];\n}\n\nexport function b2GetBodyState(world, body)\n{\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n console.assert(body.setIndex >= 0);\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // console.assert(0 <= body.localIndex && body.localIndex < set.states.count);\n return set.states.data[body.localIndex];\n }\n\n return null;\n}\n\nexport function b2CreateIslandForBody(world, setIndex, body)\n{\n console.assert(body.islandId === B2_NULL_INDEX);\n console.assert(body.islandPrev === B2_NULL_INDEX);\n console.assert(body.islandNext === B2_NULL_INDEX);\n console.assert(setIndex !== b2SetType.b2_disabledSet);\n\n const island = b2CreateIsland(world, setIndex);\n\n body.islandId = island.islandId;\n island.headBody = body.id;\n island.tailBody = body.id;\n island.bodyCount = 1;\n}\n\nexport function b2RemoveBodyFromIsland(world, body)\n{\n if (body.islandId === B2_NULL_INDEX)\n {\n // console.assert(body.islandPrev === B2_NULL_INDEX);\n // console.assert(body.islandNext === B2_NULL_INDEX);\n return;\n }\n\n const islandId = body.islandId;\n\n // b2CheckIndex(world.islandArray, islandId);\n const island = world.islandArray[islandId];\n\n // Fix the island's linked list of sims\n if (body.islandPrev !== B2_NULL_INDEX)\n {\n const prevBody = b2GetBody(world, body.islandPrev);\n prevBody.islandNext = body.islandNext;\n }\n\n if (body.islandNext !== B2_NULL_INDEX)\n {\n const nextBody = b2GetBody(world, body.islandNext);\n nextBody.islandPrev = body.islandPrev;\n }\n\n console.assert(island.bodyCount > 0);\n island.bodyCount -= 1;\n let islandDestroyed = false;\n\n if (island.headBody === body.id)\n {\n island.headBody = body.islandNext;\n\n if (island.headBody === B2_NULL_INDEX)\n {\n // Destroy empty island\n console.assert(island.tailBody === body.id);\n console.assert(island.bodyCount === 0);\n console.assert(island.contactCount === 0);\n console.assert(island.jointCount === 0);\n\n // Free the island\n b2DestroyIsland(world, island.islandId);\n islandDestroyed = true;\n }\n }\n else if (island.tailBody === body.id)\n {\n island.tailBody = body.islandPrev;\n }\n\n if (islandDestroyed === false)\n {\n b2ValidateIsland(world, islandId);\n }\n\n body.islandId = B2_NULL_INDEX;\n body.islandPrev = B2_NULL_INDEX;\n body.islandNext = B2_NULL_INDEX;\n}\n\nexport function b2DestroyBodyContacts(world, body, wakeBodies)\n{\n // Destroy the attached contacts\n let edgeKey = body.headContactKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const contactId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const contact = world.contactArray[contactId];\n edgeKey = contact.edges[edgeIndex].nextKey;\n b2DestroyContact(world, contact, wakeBodies);\n }\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2CreateBody\n * @param {b2WorldId} worldId - The ID of the world to create the body in\n * @param {b2BodyDef} def - The body definition containing initialization parameters\n * @returns {b2BodyId} The ID of the newly created body\n * @description\n * Creates a new physics body in the specified world based on the provided body definition.\n * The body is added to the appropriate solver set based on its type and state.\n * The function initializes the body's physical properties including position, rotation,\n * velocities, damping values and other simulation parameters.\n * @throws {Error} Throws assertion errors if:\n * - Position vector is invalid\n * - Rotation value is invalid\n * - Linear velocity vector is invalid\n * - Angular velocity is invalid\n * - Linear damping is invalid or negative\n * - Angular damping is invalid or negative\n * - Sleep threshold is invalid or negative\n * - Gravity scale is invalid\n */\nexport function b2CreateBody(worldId, def)\n{\n // b2CheckDef(def);\n console.assert(b2Vec2_IsValid(def.position));\n console.assert(b2Rot_IsValid(def.rotation));\n console.assert(b2Vec2_IsValid(def.linearVelocity));\n console.assert(b2IsValid(def.angularVelocity));\n console.assert(b2IsValid(def.linearDamping) && def.linearDamping >= 0.0);\n console.assert(b2IsValid(def.angularDamping) && def.angularDamping >= 0.0);\n console.assert(b2IsValid(def.sleepThreshold) && def.sleepThreshold >= 0.0);\n console.assert(b2IsValid(def.gravityScale));\n\n const world = b2GetWorldFromId(worldId);\n\n if (world.locked)\n {\n console.warn(\"Cannot create body while world is locked (are you adding a body during PreSolve callback?)\");\n\n return new b2BodyId(0, 0, 0);\n }\n\n const isAwake = (def.isAwake || def.enableSleep === false) && def.isEnabled;\n\n // determine the solver set\n let setId;\n\n if (def.isEnabled === false)\n {\n // any body type can be disabled\n setId = b2SetType.b2_disabledSet;\n }\n else if (def.type === b2BodyType.b2_staticBody)\n {\n setId = b2SetType.b2_staticSet;\n }\n else if (isAwake === true)\n {\n setId = b2SetType.b2_awakeSet;\n }\n else\n {\n // new set for a sleeping body in its own island\n setId = b2AllocId(world.solverSetIdPool);\n console.warn(\"new set for a sleeping body \" + setId);\n\n if (setId === world.solverSetArray.length)\n {\n const set = new b2SolverSet();\n set.setIndex = setId;\n world.solverSetArray.push(set);\n }\n else\n {\n console.assert(world.solverSetArray[setId].setIndex === B2_NULL_INDEX);\n }\n\n world.solverSetArray[setId].setIndex = setId;\n }\n\n // console.assert(0 <= setId && setId < world.solverSetArray.length);\n\n const bodyId = b2AllocId(world.bodyIdPool);\n\n const set = world.solverSetArray[setId];\n const bodySim = b2AddBodySim(set.sims);\n\n Object.assign(bodySim, {\n transform: new b2Transform(def.position, def.rotation),\n center: def.position.clone(),\n rotation0: def.rotation,\n center0X: def.position.x,\n center0Y: def.position.y,\n localCenter: new b2Vec2(),\n force: new b2Vec2(),\n torque: 0.0,\n mass: 0.0,\n invMass: 0.0,\n inertia: 0.0,\n invInertia: 0.0,\n minExtent: B2_HUGE,\n maxExtent: 0.0,\n linearDamping: def.linearDamping,\n angularDamping: def.angularDamping,\n gravityScale: def.gravityScale,\n bodyId: bodyId,\n isBullet: def.isBullet,\n allowFastRotation: def.allowFastRotation,\n enlargeAABB: false,\n isFast: false,\n isSpeedCapped: false\n });\n console.assert(bodySim.transform);\n\n if (setId === b2SetType.b2_awakeSet)\n {\n const bodyState = b2AddBodyState(set.states);\n console.assert((bodyState & 0x1F) === 0);\n\n Object.assign(bodyState, {\n linearVelocity: def.linearVelocity,\n angularVelocity: def.angularVelocity,\n deltaRotation: new b2Rot()\n });\n }\n\n // PJB NOTE: this 'bodyId' is the index in the world.bodyArray (so really, bodyIndex??)\n while (bodyId >= world.bodyArray.length)\n {\n world.bodyArray.push(new b2Body());\n }\n\n console.assert(world.bodyArray[bodyId].id === B2_NULL_INDEX, \"bodyId \" + bodyId + \" id \" + world.bodyArray[bodyId].id);\n\n // b2CheckIndex(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n Object.assign(body, {\n userData: def.userData,\n setIndex: setId,\n localIndex: set.sims.count - 1,\n revision: body.revision + 1,\n headShapeId: B2_NULL_INDEX,\n shapeCount: 0,\n headChainId: B2_NULL_INDEX,\n headContactKey: B2_NULL_INDEX,\n contactCount: 0,\n headJointKey: B2_NULL_INDEX, // PJB NOTE: combination of joint id (>> 1) and edge index (& 0x01)\n jointCount: 0,\n islandId: B2_NULL_INDEX,\n islandPrev: B2_NULL_INDEX,\n islandNext: B2_NULL_INDEX,\n bodyMoveIndex: B2_NULL_INDEX,\n id: bodyId, // PJB NOTE: body.id is bodyId (is index in worldBodyArray)\n sleepThreshold: def.sleepThreshold,\n sleepTime: 0.0,\n type: def.type,\n enableSleep: def.enableSleep,\n fixedRotation: def.fixedRotation,\n isSpeedCapped: false,\n isMarked: false,\n updateBodyMass: def.updateBodyMass\n });\n\n // dynamic and kinematic bodies that are enabled need an island\n if (setId >= b2SetType.b2_awakeSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n b2ValidateSolverSets(world);\n \n return new b2BodyId(bodyId + 1, world.worldId, body.revision);\n}\n\nexport function b2IsBodyAwake(world, body)\n{\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\nexport function b2WakeBody(world, body)\n{\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeSolverSet(world, body.setIndex);\n\n return true;\n }\n\n return false;\n}\n\n/**\n * @function b2DestroyBody\n * @description\n * Destroys a body and all associated joints, contacts, shapes, and chains in the physics world.\n * The function cleans up all resources and removes the body from the simulation system.\n * @param {b2BodyId} bodyId - The identifier of the body to destroy\n * @returns {void}\n * @throws {Error} Throws assertion errors if body indices are invalid during removal\n * @note This function performs the following cleanup operations:\n * - Destroys all joints connected to the body\n * - Removes all contacts associated with the body\n * - Destroys all shapes attached to the body\n * - Removes all chains connected to the body\n * - Removes the body from the island structure\n * - Cleans up solver sets and simulation data\n */\nexport function b2DestroyBody(bodyId)\n{\n // (\"b2DestroyBody \" + JSON.stringify(bodyId));\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Wake bodies attached to this body, even if this body is static.\n const wakeBodies = true;\n\n // Destroy the attached joints\n let edgeKey = body.headJointKey;\n\n while (edgeKey !== B2_NULL_INDEX)\n {\n const jointId = edgeKey >> 1;\n const edgeIndex = edgeKey & 1;\n\n const joint = world.jointArray[jointId];\n edgeKey = joint.edges[edgeIndex].nextKey;\n\n // Careful because this modifies the list being traversed\n b2DestroyJointInternal(world, joint, wakeBodies);\n }\n\n // Destroy all contacts attached to this body.\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Destroy the attached shapes and their broad-phase proxies.\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n\n b2DestroyShapeProxy(shape, world.broadPhase);\n\n // Return shape to free list.\n b2FreeId(world.shapeIdPool, shapeId);\n shape.id = B2_NULL_INDEX;\n\n shapeId = shape.nextShapeId;\n }\n\n // Destroy the attached chains. The associated shapes have already been destroyed above.\n let chainId = body.headChainId;\n\n while (chainId !== B2_NULL_INDEX)\n {\n const chain = world.chainArray[chainId];\n chain.shapeIndices = null;\n\n // Return chain to free list.\n b2FreeId(world.chainIdPool, chainId);\n chain.id = B2_NULL_INDEX;\n\n chainId = chain.nextChainId;\n }\n\n b2RemoveBodyFromIsland(world, body);\n\n // Remove body sim from solver set that owns it\n // (swap the last item in the list into its position, overwriting and removing its data)\n console.assert(body.setIndex != B2_NULL_INDEX);\n const set = world.solverSetArray[body.setIndex];\n const movedIndex = b2RemoveBodySim(set.sims, body.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n // Fix moved body index\n\n // get the body data from the set using the \n const movedSim = set.sims.data[body.localIndex];\n\n const movedId = movedSim.bodyId;\n const movedBody = world.bodyArray[movedId];\n console.assert(movedBody.localIndex === movedIndex);\n movedBody.localIndex = body.localIndex;\n }\n\n // Remove body state from awake set\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const result = b2RemoveBodyState(set.states, body.localIndex);\n\n // B2_MAYBE_UNUSED(result);\n console.assert(result === movedIndex);\n }\n else if ( set.setIndex >= b2SetType.b2_firstSleepingSet && set.sims.count == 0 )\n {\n // Remove solver set if it's now an orphan.\n b2DestroySolverSet( world, set.setIndex );\n }\n\n // Free body and id (preserve body revision)\n b2FreeId(world.bodyIdPool, body.id);\n\n body.setIndex = B2_NULL_INDEX;\n body.localIndex = B2_NULL_INDEX;\n body.id = B2_NULL_INDEX;\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * Gets the contact capacity of a body.\n * @function b2Body_GetContactCapacity\n * @param {b2BodyId} bodyId - The identifier for the body to query\n * @returns {number} The number of contacts associated with the body. Returns 0 if the world is invalid.\n * @description\n * Retrieves the current number of contacts associated with the specified body.\n * The function first validates the world reference before accessing the body's contact count.\n */\nexport function b2Body_GetContactCapacity(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n // Conservative and fast\n return body.contactCount;\n}\n\n/**\n * @function b2Body_GetContactData\n * @param {b2BodyId} bodyId - The ID of the body to get contact data from\n * @param {Array} contactData - Array to store the contact data\n * @param {number} capacity - Maximum number of contacts to retrieve\n * @returns {number} The number of contacts stored in contactData\n * @description\n * Retrieves contact data for a specified body. For each active contact, stores the shape IDs\n * of both bodies involved and the contact manifold. Only stores contacts that have the\n * touching flag set.\n * @throws {Error} If the world is locked or invalid\n */\nexport function b2Body_GetContactData(bodyId, contactData, capacity)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return 0;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n let contactKey = body.headContactKey;\n let index = 0;\n\n while (contactKey !== B2_NULL_INDEX && index < capacity)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n // b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n\n // Is contact touching?\n if (contact.flags & b2ContactFlags.b2_contactTouchingFlag)\n {\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n\n contactData[index].shapeIdA = new b2ShapeId(shapeA.id + 1, bodyId.world0, shapeA.revision);\n contactData[index].shapeIdB = new b2ShapeId(shapeB.id + 1, bodyId.world0, shapeB.revision);\n\n const contactSim = b2GetContactSim(world, contact);\n contactData[index].manifold = contactSim.manifold;\n\n index += 1;\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n console.assert(index <= capacity);\n\n return index;\n}\n\n/**\n * @function b2Body_ComputeAABB\n * @summary Computes the Axis-Aligned Bounding Box (AABB) for a body and all its shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose AABB is to be computed.\n * @returns {b2AABB} An AABB that encompasses the body and all its shapes. Returns an empty AABB if the world is not found.\n * @description\n * For bodies with no shapes, returns an AABB containing only the body's position.\n * For bodies with shapes, computes the union of AABBs of all shapes attached to the body.\n */\nexport function b2Body_ComputeAABB(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return new b2AABB();\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.headShapeId === B2_NULL_INDEX)\n {\n const transform = b2GetBodyTransform(world, body.id);\n const aabb = new b2AABB(transform.p.x, transform.p.y, transform.p.x, transform.p.y);\n\n return aabb;\n }\n\n let shape = world.shapeArray[body.headShapeId];\n let aabb = shape.aabb;\n\n while (shape.nextShapeId !== B2_NULL_INDEX)\n {\n shape = world.shapeArray[shape.nextShapeId];\n aabb = b2AABB_Union(aabb, shape.aabb);\n }\n\n return aabb;\n}\n\nexport function b2UpdateBodyMassData(world, body)\n{\n const bodySim = b2GetBodySim(world, body);\n\n // Compute mass data from shapes. Each shape has its own density.\n bodySim.mass = 0.0;\n bodySim.invMass = 0.0;\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n\n // bodySim.localCenter = new b2Vec2(); assigned in the function\n bodySim.minExtent = B2_HUGE;\n bodySim.maxExtent = 0.0;\n\n // Static and kinematic sims have zero mass.\n if (body.type !== b2BodyType.b2_dynamicBody)\n {\n bodySim.center = bodySim.transform.p.clone();\n\n // Need extents for kinematic bodies for sleeping to work correctly.\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, new b2Vec2());\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n }\n\n return;\n }\n\n // Accumulate mass over all shapes.\n let localCenter = new b2Vec2();\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n if (s.density === 0.0)\n {\n continue;\n }\n\n const massData = b2ComputeShapeMass(s);\n bodySim.mass += massData.mass;\n localCenter = b2MulAdd(localCenter, massData.mass, massData.center);\n bodySim.inertia += massData.rotationalInertia;\n }\n\n // Compute center of mass.\n console.assert(bodySim.mass > 0.0, \"A body has zero mass, check both density and size!\");\n\n if (bodySim.mass > 0.0)\n {\n bodySim.invMass = 1.0 / bodySim.mass;\n localCenter = b2MulSV(bodySim.invMass, localCenter);\n }\n\n if (bodySim.inertia > 0.0 && body.fixedRotation === false)\n {\n // Center the inertia about the center of mass.\n bodySim.inertia -= bodySim.mass * b2Dot(localCenter, localCenter);\n console.assert(bodySim.inertia > 0.0);\n bodySim.invInertia = 1.0 / bodySim.inertia;\n }\n else\n {\n bodySim.inertia = 0.0;\n bodySim.invInertia = 0.0;\n }\n\n // Move center of mass.\n const oldCenter = bodySim.center.clone();\n bodySim.localCenter = localCenter;\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n // Update center of mass velocity\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n const deltaLinear = b2CrossSV(state.angularVelocity, b2Sub(bodySim.center, oldCenter));\n state.linearVelocity = b2Add(state.linearVelocity, deltaLinear);\n }\n\n // Compute body extents relative to center of mass\n shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const s = world.shapeArray[shapeId];\n shapeId = s.nextShapeId;\n\n const extent = b2ComputeShapeExtent(s, localCenter);\n bodySim.minExtent = Math.min(bodySim.minExtent, extent.minExtent);\n bodySim.maxExtent = Math.max(bodySim.maxExtent, extent.maxExtent);\n }\n}\n\n/**\n * @function b2Body_GetPosition\n * @summary Gets the current position of a body in the physics world.\n * @param {b2BodyId} bodyId - The identifier for the body whose position is being queried.\n * @returns {b2Vec2} The position vector of the body in world coordinates.\n * @description\n * Retrieves the current position component of a body's transform from the physics world.\n * The position is returned as a b2Vec2 representing the body's location in world space.\n */\nexport function b2Body_GetPosition(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.p;\n}\n\n/**\n * Gets the rotation component of a body's transform.\n * @function b2Body_GetRotation\n * @param {b2BodyId} bodyId - The identifier for the body whose rotation is being queried.\n * @returns {b2Rot} A rotation object containing the cosine and sine of the body's angle.\n * @description\n * Retrieves the rotation component (q) from the body's transform. The returned b2Rot\n * object represents the body's angular orientation in 2D space.\n */\nexport function b2Body_GetRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return transform.q;\n}\n\n/**\n * @summary Gets the transform of a body in the physics world.\n * @function b2Body_GetTransform\n * @param {Object} bodyId - The identifier object for the body, containing world reference.\n * @param {number} bodyId.world0 - The world identifier.\n * @returns {Object} The body's transform containing:\n * - position {b2Vec2} The position vector (x, y)\n * - rotation {b2Rot} The rotation values (c, s)\n * @description\n * Retrieves the current transform (position and rotation) of a physics body\n * from the specified Box2D world using the body's identifier.\n */\nexport function b2Body_GetTransform(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return b2GetBodyTransformQuick(world, body);\n}\n\n/**\n * Converts a point from world coordinates to local body coordinates.\n * @function b2Body_GetLocalPoint\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldPoint - A point in world coordinates\n * @returns {b2Vec2} The point expressed in the body's local coordinates\n * @description\n * Takes a point given in world coordinates and converts it to the body's local\n * coordinate system by applying the inverse of the body's transform.\n */\nexport function b2Body_GetLocalPoint(bodyId, worldPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvTransformPoint(transform, worldPoint);\n}\n\n/**\n * @function b2Body_GetWorldPoint\n * @summary Converts a point from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @param {b2Vec2} localPoint - A point in the body's local coordinates.\n * @returns {b2Vec2} The point transformed to world coordinates.\n * @description\n * Takes a point given in body-local coordinates and converts it to world coordinates\n * using the body's current transform (position and rotation).\n */\nexport function b2Body_GetWorldPoint(bodyId, localPoint)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2TransformPoint(transform, localPoint);\n}\n\n/**\n * @function b2Body_GetLocalVector\n * @summary Converts a vector from world space to a body's local space\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} worldVector - A vector in world coordinates\n * @returns {b2Vec2} The vector transformed into the body's local coordinates\n * @description\n * Takes a vector defined in world coordinates and transforms it to be relative\n * to the body's local coordinate system by applying the inverse of the body's rotation.\n */\nexport function b2Body_GetLocalVector(bodyId, worldVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2InvRotateVector(transform.q, worldVector);\n}\n\n/**\n * @function b2Body_GetWorldVector\n * @summary Converts a vector from local body coordinates to world coordinates.\n * @param {b2BodyId} bodyId - The identifier for the body\n * @param {b2Vec2} localVector - A vector in local body coordinates\n * @returns {b2Vec2} The vector transformed into world coordinates\n * @description\n * Transforms a vector from the body's local coordinate system to the world\n * coordinate system. This operation only performs rotation (not translation)\n * using the body's current rotation matrix.\n */\nexport function b2Body_GetWorldVector(bodyId, localVector)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n return b2RotateVector(transform.q, localVector);\n}\n\n/**\n * @function b2Body_SetTransform\n * @description\n * Sets the position and rotation of a body, updating its transform and associated shape AABBs.\n * The function updates the body's center, handles broad-phase movement, and adjusts collision bounds.\n * @param {b2BodyId} bodyId - The identifier of the body to transform\n * @param {b2Vec2} position - The new position vector for the body\n * @param {b2Rot} [rotation] - The new rotation for the body. If undefined, keeps current rotation\n * @returns {void}\n * @throws {Error} Throws assertion error if:\n * - The position vector is invalid\n * - The body ID is invalid\n * - The world is locked\n * - The rotation (if provided) is invalid\n */\nexport function b2Body_SetTransform(bodyId, position, rotation)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n console.assert(world.locked === false);\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n console.assert(b2Rot_IsValid(rotation) || b2Rot_IsValid(bodySim.transform.q));\n\n bodySim.transform.p = position;\n\n if (rotation !== undefined)\n {\n bodySim.transform.q = rotation;\n }\n bodySim.center = b2TransformPoint(bodySim.transform, bodySim.localCenter);\n\n bodySim.rotation0 = bodySim.transform.q;\n bodySim.center0X = bodySim.center.x;\n bodySim.center0Y = bodySim.center.y;\n\n const broadPhase = world.broadPhase;\n\n const transform = bodySim.transform;\n const margin = b2_aabbMargin;\n const speculativeDistance = b2_speculativeDistance;\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = b2ComputeShapeAABB(shape, transform);\n aabb.lowerBoundX -= speculativeDistance;\n aabb.lowerBoundY -= speculativeDistance;\n aabb.upperBoundX += speculativeDistance;\n aabb.upperBoundY += speculativeDistance;\n shape.aabb = aabb;\n\n if (b2AABB_Contains(shape.fatAABB, aabb) === false)\n {\n const fatAABB = new b2AABB(aabb.lowerBoundX - margin, aabb.lowerBoundY - margin,\n aabb.upperBoundX + margin, aabb.upperBoundY + margin);\n shape.fatAABB = fatAABB;\n\n // The body could be disabled\n if (shape.proxyKey !== B2_NULL_INDEX)\n {\n b2BroadPhase_MoveProxy(broadPhase, shape.proxyKey, fatAABB);\n }\n }\n\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * Gets a clone of the linear velocity of a body.\n * @function b2Body_GetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The linear velocity vector of the body. Returns a zero vector (0,0) if the body state is null.\n * @description\n * Retrieves the current linear velocity of a body from its state in the physics world.\n * If the body state cannot be found, returns a zero vector.\n * Linear velocity is often used for calculations (damping, direction, etc) and must be cloned to avoid unwanted effects in the Physics engine.\n */\nexport function b2Body_GetLinearVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.linearVelocity.clone();\n }\n\n return new b2Vec2();\n}\n\n/**\n * Gets the angular velocity of a body.\n * @function b2Body_GetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular velocity in radians per second. Returns 0 if the body state cannot be retrieved.\n * @description\n * Retrieves the current angular velocity of a body from its state in the physics world.\n * Angular velocity represents how fast the body is rotating.\n */\nexport function b2Body_GetAngularVelocity(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n return state.angularVelocity;\n }\n\n return 0.0;\n}\n\n/**\n * Sets the linear velocity of a body.\n * @function b2Body_SetLinearVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {b2Vec2} linearVelocity - The new linear velocity vector to set.\n * @returns {void}\n * @description\n * Sets the linear velocity of a body. If the body is static, the function returns without\n * making changes. If the new velocity has a non-zero magnitude, the body will be awakened.\n * The function will return early if the body state cannot be retrieved.\n */\nexport function b2Body_SetLinearVelocity(bodyId, linearVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody)\n {\n return;\n }\n\n if (b2LengthSquared(linearVelocity) > 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.linearVelocity = linearVelocity;\n}\n\n/**\n * Sets the angular velocity of a body.\n * @function b2Body_SetAngularVelocity\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {number} angularVelocity - The new angular velocity in radians per second\n * @returns {void}\n * @description\n * Sets the angular velocity of a body. If the body is static or has fixed rotation,\n * the function returns without making changes. The body is woken up if a non-zero\n * angular velocity is set.\n */\nexport function b2Body_SetAngularVelocity(bodyId, angularVelocity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.type == b2BodyType.b2_staticBody || body.fixedRotation)\n {\n return;\n }\n \n if (angularVelocity !== 0.0)\n {\n b2WakeBody(world, body);\n }\n\n const state = b2GetBodyState(world, body);\n\n if (state === null)\n {\n return;\n }\n\n state.angularVelocity = angularVelocity;\n}\n\n/**\n * @function b2Body_ApplyForce\n * @description\n * Applies a force at a world point to a body. If the force is not applied at the\n * center of mass, it will generate a torque and affect angular motion.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector\n * @param {b2Vec2} point - The world position of the point of application\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n * @note The force is accumulated and applied during the next time step. The body\n * must be awake for the force to be applied.\n */\nexport function b2Body_ApplyForce(bodyId, force, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n bodySim.torque += b2Cross(b2Sub(point, bodySim.center), force);\n }\n}\n\n/**\n * @function b2Body_ApplyForceToCenter\n * @description\n * Applies a force to the center of mass of a body. If the body is sleeping, it can optionally be woken up.\n * The force is only applied if the body is in the awake set.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the force to\n * @param {b2Vec2} force - The world force vector to apply to the body's center\n * @param {boolean} wake - Whether to wake the body if it is sleeping\n * @returns {void}\n */\nexport function b2Body_ApplyForceToCenter(bodyId, force, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.force = b2Add(bodySim.force, force);\n }\n}\n\n/**\n * @function b2Body_ApplyTorque\n * @summary Applies a torque to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to apply torque to\n * @param {number} torque - The amount of torque to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @description\n * Adds the specified torque to the body's total torque. If the wake parameter\n * is true and the body is sleeping, it will be awakened. The torque is only\n * applied if the body is in the awake set.\n */\nexport function b2Body_ApplyTorque(bodyId, torque, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const bodySim = b2GetBodySim(world, body);\n bodySim.torque += torque;\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulse\n * @description\n * Applies a linear impulse to a body at a specified world point, affecting both its linear\n * and angular velocities.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The world impulse vector to apply\n * @param {b2Vec2} point - The world position where the impulse is applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body's local index is invalid\n */\nexport function b2Body_ApplyLinearImpulse(bodyId, impulse, point, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(point, bodySim.center), impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyLinearImpulseToCenter\n * @description\n * Applies a linear impulse to the center of mass of a body. If the body is sleeping,\n * it can optionally be woken up.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {b2Vec2} impulse - The linear impulse vector to be applied\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @note The impulse is applied immediately, changing the body's linear velocity based\n * on its mass and the magnitude/direction of the impulse.\n */\nexport function b2Body_ApplyLinearImpulseToCenter(bodyId, impulse, wake)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n }\n}\n\n/**\n * @function b2Body_ApplyAngularImpulse\n * @description\n * Applies an angular impulse to a body, affecting its angular velocity. The impulse is\n * scaled by the body's inverse inertia.\n * @param {b2BodyId} bodyId - The identifier of the body to apply the impulse to\n * @param {number} impulse - The angular impulse to apply\n * @param {boolean} wake - Whether to wake the body if it's sleeping\n * @returns {void}\n * @throws {Error} Throws an assertion error if the body ID is invalid or if the body\n * revision doesn't match\n */\nexport function b2Body_ApplyAngularImpulse(bodyId, impulse, wake)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n\n const id = bodyId.index1 - 1;\n\n // b2CheckIndex(world.bodyArray, id);\n const body = world.bodyArray[id];\n console.assert(body.revision === bodyId.revision);\n\n if (wake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n // this will not invalidate body pointer\n b2WakeBody(world, body);\n }\n\n if (body.setIndex === b2SetType.b2_awakeSet)\n {\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const sim = set.sims.data[localIndex];\n state.angularVelocity += sim.invInertia * impulse;\n }\n}\n\n/**\n * Gets the type of a body in the physics world.\n * @function b2Body_GetType\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {b2BodyType} The type of the specified body.\n * @description\n * Retrieves the body type (static, kinematic, or dynamic) for a given body ID\n * by looking up the body in the physics world using the provided identifier.\n */\nexport function b2Body_GetType(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.type;\n}\n\n// Changing the body type is quite complex mainly due to joints.\n// Considerations:\n// - body and joints must be moved to the correct set\n// - islands must be updated\n// - graph coloring must be correct\n// - any body connected to a joint may be disabled\n// - joints between static bodies must go into the static set\n/**\n * @function b2Body_SetType\n * @summary Changes the type of a body in the physics simulation.\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {b2BodyType} type - The new body type to set (static, kinematic, or dynamic)\n * @returns {void}\n * @description\n * Updates a body's type and handles all necessary simulation changes including:\n * - Destroying existing contacts\n * - Waking the body and connected bodies\n * - Unlinking and relinking joints\n * - Transferring the body between solver sets\n * - Updating broad-phase proxies\n * - Recalculating mass data\n * If the body is disabled or the type is unchanged, minimal processing occurs.\n * Special handling exists for transitions to/from static body type.\n */\nexport function b2Body_SetType(bodyId, type)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n const originalType = body.type;\n\n if (originalType === type)\n {\n return;\n }\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n // Disabled bodies don't change solver sets or islands when they change type.\n body.type = type;\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n return;\n }\n\n // Destroy all contacts but don't wake bodies.\n const wakeBodies = false;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Wake this body because we assume below that it is awake or static.\n b2WakeBody(world, body);\n\n // Unlink all joints and wake attached bodies.\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // A body going from static to dynamic or kinematic goes to the awake set\n // and other attached bodies must be awake as well. For consistency, this is\n // done for all cases.\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n body.type = type;\n\n if (originalType === b2BodyType.staticBody)\n {\n // Body is going from static to dynamic or kinematic. It only makes sense to move it to the awake set.\n console.assert(body.setIndex === b2SetType.b2_staticSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to awake set\n b2TransferBody(world, awakeSet, staticSet, body);\n\n // Create island for body\n b2CreateIslandForBody(world, b2SetType.b2_awakeSet, body);\n\n // Transfer static joints to awake set\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n // Transfer the joint if it is in the static set\n if (joint.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else if (joint.setIndex === b2SetType.b2_awakeSet)\n {\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n else\n {\n // Otherwise the joint must be disabled.\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n // Recreate shape proxies in movable tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n const proxyType = type;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // @ts-ignore\n else if (type === b2BodyType.b2_staticBody)\n {\n // The body is going from dynamic/kinematic to static. It should be awake.\n console.assert(body.setIndex === b2SetType.b2_awakeSet);\n\n const staticSet = world.solverSetArray[b2SetType.b2_staticSet];\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n // Transfer body to static set\n b2TransferBody(world, staticSet, awakeSet, body);\n\n // Remove body from island.\n b2RemoveBodyFromIsland(world, body);\n\n // Maybe transfer joints to static set.\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n // Skip disabled joint\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n // Joint is disable, should be connected to a disabled body\n console.assert(otherBody.setIndex === b2SetType.b2_disabledSet);\n\n continue;\n }\n\n // Since the body was not static, the joint must be awake.\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n\n // Only transfer joint to static set if both bodies are static.\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n b2TransferJoint(world, staticSet, awakeSet, joint);\n }\n else\n {\n // The other body must be awake.\n console.assert(otherBody.setIndex === b2SetType.b2_awakeSet);\n\n // The joint must live in a graph color.\n console.assert(0 <= joint.colorIndex && joint.colorIndex < b2_graphColorCount);\n\n // In this case the joint must be re-inserted into the constraint graph to ensure the correct\n // graph color.\n\n // First transfer to the static set.\n b2TransferJoint(world, staticSet, awakeSet, joint);\n\n // Now transfer it back to the awake set and into the graph coloring.\n b2TransferJoint(world, awakeSet, staticSet, joint);\n }\n }\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, b2BodyType.b2_staticBody, transform, forcePairCreation);\n }\n }\n else\n {\n console.assert(originalType === b2BodyType.b2_dynamicBody || originalType === b2BodyType.b2_kinematicBody);\n\n // @ts-ignore\n console.assert(type === b2BodyType.b2_dynamicBody || type === b2BodyType.b2_kinematicBody);\n\n // Recreate shape proxies in static tree.\n const transform = b2GetBodyTransformQuick(world, body);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n const proxyType = type;\n const forcePairCreation = true;\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n }\n\n // Relink all joints\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const otherEdgeIndex = edgeIndex ^ 1;\n const otherBodyId = joint.edges[otherEdgeIndex].bodyId;\n\n // b2CheckIndex(world.bodyArray, otherBodyId);\n const otherBody = world.bodyArray[otherBodyId];\n\n if (otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n if (body.type === b2BodyType.b2_staticBody && otherBody.type === b2BodyType.b2_staticBody)\n {\n continue;\n }\n\n b2LinkJoint(world, joint, false);\n }\n\n b2MergeAwakeIslands(world);\n }\n\n // Body type affects the mass\n b2UpdateBodyMassData(world, body);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @summary Sets the user data associated with a body.\n * @function b2Body_SetUserData\n * @param {b2BodyId} bodyId - The identifier of the body to modify.\n * @param {*} userData - The user data to associate with the body.\n * @returns {void}\n * @description\n * Associates arbitrary user data with a physics body. The user data can be\n * retrieved later and can be of any type. The body is located using its\n * world identifier and the user data is stored directly on the body object.\n */\nexport function b2Body_SetUserData(bodyId, userData)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.userData = userData;\n}\n\n/**\n * @summary Gets the user data associated with a body.\n * @function b2Body_GetUserData\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {object} The user data associated with the body.\n * @description\n * Retrieves the custom user data that was previously attached to the specified body.\n * The function first gets the world from the body ID, then retrieves the full body\n * object, and finally returns its user data.\n */\nexport function b2Body_GetUserData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.userData;\n}\n\n/**\n * Gets the mass of a body.\n * @function b2Body_GetMass\n * @param {b2BodyId} bodyId - The identifier for the body whose mass is to be retrieved.\n * @returns {number} The mass of the body in kilograms.\n * @description\n * Retrieves the mass value from a body's simulation data by accessing the world\n * and body objects using the provided body identifier.\n */\nexport function b2Body_GetMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.mass;\n}\n\n/**\n * Get the rotational inertia of the body, typically in kg*m^2\n * @function b2Body_GetRotationalInertia\n * @param {b2BodyId} bodyId - The ID of the body to get the inertia tensor from.\n * @returns {number} The inertia tensor value of the body.\n * @description\n * Retrieves the rotational inertia value from a body's simulation data using the body's ID.\n * The inertia tensor represents the body's resistance to rotational acceleration.\n */\nexport function b2Body_GetRotationalInertia(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.inertia;\n}\n\n/**\n * Gets the local center of mass for a body.\n * @function b2Body_GetLocalCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {b2Vec2} The local center of mass position vector.\n * @description\n * Returns a copy of the body's local center of mass position vector.\n * The local center is expressed in the body's local coordinate system.\n */\nexport function b2Body_GetLocalCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.localCenter.clone();\n}\n\n/**\n * Gets the world position of a body's center of mass.\n * @function b2Body_GetWorldCenterOfMass\n * @param {b2BodyId} bodyId - The identifier for the body whose center of mass position is being queried.\n * @returns {b2Vec2} A vector representing the world position of the body's center of mass.\n * @description\n * Returns a copy of the body's center of mass position in world coordinates.\n * The returned vector is a clone of the internal state, preventing external\n * modification of the body's actual center position.\n */\nexport function b2Body_GetWorldCenterOfMass(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.center.clone();\n}\n\n/**\n * @function b2Body_SetMassData\n * @description\n * Sets the mass properties of a body including mass, rotational inertia, and center of mass.\n * The function updates both the primary mass properties and derived values like inverse mass.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {b2MassData} massData - An object containing:\n * - mass: The mass of the body (must be >= 0)\n * - rotationalInertia: The rotational inertia (must be >= 0)\n * - center: A b2Vec2 representing the local center of mass\n * @returns {void}\n * @throws {Error} Throws assertion error if mass or rotationalInertia are invalid or negative,\n * or if the center vector is invalid\n */\nexport function b2Body_SetMassData(bodyId, massData)\n{\n console.assert(b2IsValid(massData.mass) && massData.mass >= 0.0);\n console.assert(b2IsValid(massData.rotationalInertia) && massData.rotationalInertia >= 0.0);\n console.assert(b2Vec2_IsValid(massData.center));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n bodySim.mass = massData.mass;\n bodySim.inertia = massData.rotationalInertia;\n bodySim.localCenter = massData.center;\n\n const center = b2TransformPoint(bodySim.transform, massData.center);\n bodySim.center = center;\n bodySim.center0X = center.x;\n bodySim.center0Y = center.y;\n\n bodySim.invMass = bodySim.mass > 0.0 ? 1.0 / bodySim.mass : 0.0;\n bodySim.invInertia = bodySim.inertia > 0.0 ? 1.0 / bodySim.inertia : 0.0;\n}\n\n/**\n * @function b2Body_GetMassData\n * @param {b2BodyId} bodyId - The identifier for the body whose mass data is being retrieved\n * @returns {b2MassData} An object containing mass properties:\n * - mass: The total mass of the body\n * - center: A b2Vec2 representing the local center of mass\n * - rotationalInertia: The rotational inertia about the local center of mass\n * @description\n * Retrieves the mass properties of a body, including its total mass,\n * center of mass position, and rotational inertia.\n */\nexport function b2Body_GetMassData(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n const massData = new b2MassData();\n massData.mass = bodySim.mass;\n massData.center = bodySim.localCenter;\n massData.rotationalInertia = bodySim.inertia;\n\n return massData;\n}\n\n/**\n * @function b2Body_ApplyMassFromShapes\n * @summary Updates a body's mass properties based on its attached shapes.\n * @param {b2BodyId} bodyId - The identifier for the body whose mass properties need to be updated.\n * @returns {void}\n * @description\n * This function retrieves the body from the world using its ID and updates its mass data\n * properties (mass, center of mass, and rotational inertia) based on the shapes attached to it.\n * If the world cannot be accessed, the function returns without performing any operations.\n */\nexport function b2Body_ApplyMassFromShapes(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n b2UpdateBodyMassData(world, body);\n}\n\n/**\n * Sets the linear damping value for a body.\n * @function b2Body_SetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} linearDamping - The new linear damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the linear damping coefficient for a body, which reduces its linear velocity over time.\n * Linear damping is used to simulate air resistance or fluid friction.\n * @throws {Error} Throws an assertion error if linearDamping is invalid or negative.\n */\nexport function b2Body_SetLinearDamping(bodyId, linearDamping)\n{\n console.assert(b2IsValid(linearDamping) && linearDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.linearDamping = linearDamping;\n}\n\n/**\n * Gets the linear damping coefficient of a body.\n * @function b2Body_GetLinearDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The linear damping coefficient of the body.\n * @description\n * Returns the linear damping coefficient that reduces the body's linear velocity.\n * Linear damping is used to reduce the linear velocity of the body in the absence\n * of forces. The damping parameter can be used to simulate fluid/air resistance.\n */\nexport function b2Body_GetLinearDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.linearDamping;\n}\n\n/**\n * @summary Sets the angular damping value for a body.\n * @function b2Body_SetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the target body.\n * @param {number} angularDamping - The new angular damping value. Must be non-negative.\n * @returns {void}\n * @description\n * Sets the angular damping coefficient for a body, which reduces its angular velocity over time.\n * Angular damping is a value between 0 and infinity that reduces the body's angular velocity.\n * @throws {Error} Throws an assertion error if angularDamping is invalid or negative.\n */\nexport function b2Body_SetAngularDamping(bodyId, angularDamping)\n{\n console.assert(b2IsValid(angularDamping) && angularDamping >= 0.0);\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.angularDamping = angularDamping;\n}\n\n/**\n * Gets the angular damping coefficient of a body.\n * @function b2Body_GetAngularDamping\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The angular damping coefficient of the body.\n * @description\n * Returns the angular damping coefficient that reduces the body's angular velocity\n * over time. Angular damping is specified in the range [0,1].\n */\nexport function b2Body_GetAngularDamping(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.angularDamping;\n}\n\n/**\n * @function b2Body_SetGravityScale\n * @summary Sets the gravity scale factor for a body.\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} gravityScale - The scaling factor to apply to gravity for this body.\n * @returns {void}\n * @throws {Error} Throws an assertion error if bodyId is invalid or if gravityScale is not a valid number.\n * @description\n * Sets a scale factor that modifies the effect of gravity on a specific body.\n * A value of 1.0 indicates normal gravity, 0.0 indicates no gravity, and negative\n * values reverse the effect of gravity on the body.\n */\nexport function b2Body_SetGravityScale(bodyId, gravityScale)\n{\n console.assert(b2Body_IsValid(bodyId));\n console.assert(b2IsValid(gravityScale));\n\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.gravityScale = gravityScale;\n}\n\n/**\n * Gets the gravity scale of a body.\n * @function b2Body_GetGravityScale\n * @param {b2BodyId} bodyId - The identifier of the body to query.\n * @returns {number} The gravity scale factor of the body.\n * @throws {Error} Throws an assertion error if the bodyId is invalid.\n */\nexport function b2Body_GetGravityScale(bodyId)\n{\n console.assert(b2Body_IsValid(bodyId));\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.gravityScale;\n}\n\n/**\n * @summary Checks if a body is in the awake set.\n * @function b2Body_IsAwake\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is in the awake set, false otherwise.\n * @description\n * Determines if a body is currently in the awake set by checking its set index\n * against the b2_awakeSet type. Bodies in the awake set are actively participating\n * in the simulation.\n */\nexport function b2Body_IsAwake(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex === b2SetType.b2_awakeSet;\n}\n\n/**\n * @summary Sets the awake state of a physics body\n * @function b2Body_SetAwake\n * @param {b2BodyId} bodyId - The ID of the body to modify\n * @param {boolean} awake - True to wake the body, false to put it to sleep\n * @returns {void}\n * @description\n * Controls whether a physics body is awake (active) or asleep (inactive).\n * When setting a body to sleep, it will split islands if there are pending constraint removals.\n * When waking a body, it will be moved from the sleeping set to the awake set.\n */\nexport function b2Body_SetAwake(bodyId, awake)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (awake && body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n b2WakeBody(world, body);\n }\n else if (awake === false && body.setIndex === b2SetType.b2_awakeSet)\n {\n // b2CheckIndex(world.islandArray, body.islandId);\n const island = world.islandArray[body.islandId];\n\n if (island.constraintRemoveCount > 0)\n {\n b2SplitIsland(world, body.islandId);\n }\n\n b2TrySleepIsland(world, body.islandId);\n }\n}\n\n/**\n * @summary Checks if a body is enabled in the physics simulation.\n * @function b2Body_IsEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is enabled, false if disabled.\n * @description\n * Determines if a physics body is enabled by checking if it belongs to the\n * disabled set. A disabled body does not participate in collision detection\n * or dynamics simulation.\n */\nexport function b2Body_IsEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.setIndex !== b2SetType.b2_disabledSet;\n}\n\n/**\n * @summary Checks if sleep is enabled for a body.\n * @function b2Body_IsSleepEnabled\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if sleep is enabled for the body, false otherwise.\n * @description\n * Returns whether the specified body has sleep enabled. When sleep is enabled,\n * the body can automatically enter a sleep state when it becomes inactive.\n */\nexport function b2Body_IsSleepEnabled(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.enableSleep;\n}\n\n/**\n * Sets the sleep threshold velocity for a body.\n * @function b2Body_SetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body to modify.\n * @param {number} sleepThreshold - The velocity threshold below which the body can sleep.\n * @returns {void}\n * @description\n * Sets the minimum velocity threshold that determines when a body can transition to a sleeping state.\n * When a body's velocity falls below this threshold, it becomes eligible for sleeping.\n */\nexport function b2Body_SetSleepThreshold(bodyId, sleepThreshold)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n body.sleepThreshold = sleepThreshold;\n}\n\n/**\n * Gets the sleep threshold value for a body.\n * @function b2Body_GetSleepThreshold\n * @param {b2BodyId} bodyId - The identifier for the body.\n * @returns {number} The sleep threshold value for the body.\n * @description\n * Returns the minimum speed threshold below which a body can be put to sleep\n * to optimize simulation performance.\n */\nexport function b2Body_GetSleepThreshold(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.sleepThreshold;\n}\n\n/**\n * @function b2Body_EnableSleep\n * @description\n * Enables or disables sleep capability for a specific body. When sleep is disabled,\n * the body will be woken if it was sleeping.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} enableSleep - True to enable sleep capability, false to disable it\n * @returns {void}\n * @throws {Error} If the world associated with the bodyId is not found\n */\nexport function b2Body_EnableSleep(bodyId, enableSleep)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n body.enableSleep = enableSleep;\n\n if (enableSleep === false)\n {\n b2WakeBody(world, body);\n }\n}\n\n// Disabling a body requires a lot of detailed bookkeeping, but it is a valuable feature.\n// The most challenging aspect that joints may connect to bodies that are not disabled.\n/**\n * @function b2Body_Disable\n * @param {b2BodyId} bodyId - The identifier of the body to disable\n * @returns {void}\n * @description\n * Disables a body in the physics simulation by removing it from its current solver set\n * and moving it to the disabled set. The function removes all contacts associated with\n * the body, removes it from any island it belongs to, destroys shape proxies in the\n * broad phase, and transfers associated joints to the disabled set.\n * @throws {Error} Throws if the world is locked or invalid\n */\nexport function b2Body_Disable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex === b2SetType.b2_disabledSet)\n {\n return;\n }\n\n // Destroy contacts and wake bodies touching this body. This avoid floating bodies.\n // This is necessary even for static bodies.\n const wakeBodies = true;\n b2DestroyBodyContacts(world, body, wakeBodies);\n\n // Disabled bodies are not in an island.\n b2RemoveBodyFromIsland(world, body);\n\n // Remove shapes from broad-phase\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n b2DestroyShapeProxy(shape, world.broadPhase);\n }\n\n // Transfer simulation data to disabled set\n // b2CheckIndex(world.solverSetArray, body.setIndex);\n const set = world.solverSetArray[body.setIndex];\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n\n // Transfer body sim\n b2TransferBody(world, disabledSet, set, body);\n\n // Unlink joints and transfer\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n jointKey = joint.edges[edgeIndex].nextKey;\n\n // joint may already be disabled by other body\n if (joint.setIndex === b2SetType.b2_disabledSet)\n {\n continue;\n }\n\n console.assert(joint.setIndex === set.setIndex || set.setIndex === b2SetType.b2_staticSet);\n\n // Remove joint from island\n if (joint.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkJoint(world, joint);\n }\n\n // Transfer joint to disabled set\n // b2CheckIndex(world.solverSetArray, joint.setIndex);\n const jointSet = world.solverSetArray[joint.setIndex];\n b2TransferJoint(world, disabledSet, jointSet, joint);\n }\n\n b2ValidateConnectivity(world);\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_Enable\n * @description\n * Enables a previously disabled body in the physics world. When enabled, the body's\n * shapes are added to the broad-phase collision system, and its joints are\n * reconnected to the simulation. The body is moved from the disabled set to either\n * the static set or awake set based on its type.\n * @param {b2BodyId} bodyId - The identifier of the body to enable\n * @returns {void}\n * @throws {Error} Throws an assertion error if joint connectivity validation fails\n */\nexport function b2Body_Enable(bodyId)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.setIndex !== b2SetType.b2_disabledSet)\n {\n return;\n }\n\n const disabledSet = world.solverSetArray[b2SetType.b2_disabledSet];\n const setId = body.type === b2BodyType.b2_staticBody ? b2SetType.b2_staticSet : b2SetType.b2_awakeSet;\n const targetSet = world.solverSetArray[setId];\n\n b2TransferBody(world, targetSet, disabledSet, body);\n\n const transform = b2GetBodyTransformQuick(world, body);\n\n // Add shapes to broad-phase\n const proxyType = body.type;\n const forcePairCreation = true;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shapeId = shape.nextShapeId;\n\n b2CreateShapeProxy(shape, world.broadPhase, proxyType, transform, forcePairCreation);\n }\n\n if (setId !== b2SetType.b2_staticSet)\n {\n b2CreateIslandForBody(world, setId, body);\n }\n\n // Transfer joints. If the other body is disabled, don't transfer.\n // If the other body is sleeping, wake it.\n const mergeIslands = false;\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n console.assert(joint.islandId === B2_NULL_INDEX);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n\n const bodyA = world.bodyArray[joint.edges[0].bodyId];\n const bodyB = world.bodyArray[joint.edges[1].bodyId];\n\n if (bodyA.setIndex === b2SetType.b2_disabledSet || bodyB.setIndex === b2SetType.b2_disabledSet)\n {\n // one body is still disabled\n continue;\n }\n\n // Transfer joint first\n let jointSetId;\n\n if (bodyA.setIndex === b2SetType.b2_staticSet && bodyB.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = b2SetType.b2_staticSet;\n }\n else if (bodyA.setIndex === b2SetType.b2_staticSet)\n {\n jointSetId = bodyB.setIndex;\n }\n else\n {\n jointSetId = bodyA.setIndex;\n }\n\n // b2CheckIndex(world.solverSetArray, jointSetId);\n const jointSet = world.solverSetArray[jointSetId];\n b2TransferJoint(world, jointSet, disabledSet, joint);\n\n // Now that the joint is in the correct set, I can link the joint in the island.\n if (jointSetId !== b2SetType.b2_staticSet)\n {\n b2LinkJoint(world, joint, mergeIslands);\n }\n }\n\n // Now merge islands\n b2MergeAwakeIslands(world);\n\n b2ValidateSolverSets(world);\n}\n\n/**\n * @function b2Body_SetFixedRotation\n * @summary Sets whether a body should have fixed rotation.\n * @param {b2BodyId} bodyId - The identifier for the body to modify\n * @param {boolean} flag - True to fix the rotation, false to allow rotation\n * @returns {void}\n * @description\n * Sets the fixed rotation state of a body. When enabled, the body will not rotate\n * and any existing angular velocity is cleared. The body's mass data is updated\n * to reflect the change in rotational constraints.\n */\nexport function b2Body_SetFixedRotation(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n\n if (body.fixedRotation !== flag)\n {\n body.fixedRotation = flag;\n const state = b2GetBodyState(world, body);\n\n if (state !== null)\n {\n state.angularVelocity = 0.0;\n }\n b2UpdateBodyMassData(world, body);\n }\n}\n\n/**\n * @function b2Body_IsFixedRotation\n * @param {b2BodyId} bodyId - The identifier for the body to check\n * @returns {boolean} True if the body has fixed rotation enabled, false otherwise\n * @description\n * Checks whether a body has fixed rotation enabled. When fixed rotation is enabled,\n * the body will not rotate in response to torques or collisions.\n */\nexport function b2Body_IsFixedRotation(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.fixedRotation;\n}\n\n/**\n * @function b2Body_SetBullet\n * @summary Sets the bullet flag on a physics body.\n * @param {b2BodyId} bodyId - The identifier for the physics body.\n * @param {boolean} flag - True to enable bullet mode, false to disable it.\n * @returns {void}\n * @description\n * Sets whether a body should be treated as a bullet for continuous collision detection.\n * Bullet bodies are designed for fast moving objects that require more precise\n * collision detection.\n */\nexport function b2Body_SetBullet(bodyId, flag)\n{\n const world = b2GetWorldLocked(bodyId.world0);\n\n if (world === null)\n {\n return;\n }\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n bodySim.isBullet = flag;\n}\n\n/**\n * @function b2Body_IsBullet\n * @summary Checks if a body has bullet status.\n * @param {b2BodyId} bodyId - The identifier for the body to check.\n * @returns {boolean} True if the body is a bullet, false otherwise.\n * @description\n * Retrieves the bullet status of a body from the physics simulation.\n * Bullet bodies undergo continuous collision detection for improved\n * accuracy with fast-moving objects.\n */\nexport function b2Body_IsBullet(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n const bodySim = b2GetBodySim(world, body);\n\n return bodySim.isBullet;\n}\n\n/**\n * @function b2Body_EnableHitEvents\n * @description\n * Enables or disables hit event detection for all shapes attached to a body.\n * @param {b2BodyId} bodyId - The identifier of the body to modify\n * @param {boolean} enableHitEvents - Whether to enable or disable hit events\n * @returns {void}\n */\nexport function b2Body_EnableHitEvents(bodyId, enableHitEvents)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n shape.enableHitEvents = enableHitEvents;\n shapeId = shape.nextShapeId;\n }\n}\n\n/**\n * @summary Gets the number of shapes attached to a body.\n * @function b2Body_GetShapeCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of shapes attached to the body.\n * @description\n * Returns the total count of shapes currently attached to the specified body\n * in the physics world.\n */\nexport function b2Body_GetShapeCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.shapeCount;\n}\n\n/**\n * @function b2Body_GetShapes\n * @summary Gets all shapes attached to a body and returns the count.\n * @param {b2BodyId} bodyId - The identifier of the body to get shapes from.\n * @param {b2ShapeId[]} shapeArray - An array to store the retrieved shape IDs.\n * @returns {number} The number of shapes found on the body.\n * @description\n * Retrieves all shapes attached to the specified body by traversing the linked list\n * of shapes starting from the body's headShapeId. Each shape ID is stored in the\n * provided shapeArray and the total count is returned.\n * If shapeArray is already large enough we can avoid the overhead of growing the array.\n */\nexport function b2Body_GetShapes(bodyId, shapeArray)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let shapeId = body.headShapeId;\n let shapeCount = 0;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const id = new b2ShapeId(shape.id + 1, bodyId.world0, shape.revision);\n shapeArray[shapeCount] = id;\n shapeCount += 1;\n shapeId = shape.nextShapeId;\n }\n\n return shapeCount;\n}\n\n/**\n * @summary Gets the number of joints connected to a body.\n * @function b2Body_GetJointCount\n * @param {b2BodyId} bodyId - The identifier for the body to query.\n * @returns {number} The number of joints connected to the body.\n * @description\n * Returns the total count of joints that are connected to the specified body.\n */\nexport function b2Body_GetJointCount(bodyId)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n\n return body.jointCount;\n}\n\n/**\n * @function b2Body_GetJoints\n * @summary Gets all joints connected to a body.\n * @param {b2BodyId} bodyId - The ID of the body to get joints for\n * @param {b2JointId[]} jointArray - Array to store the joint IDs\n * @param {number} capacity - Maximum number of joints to retrieve\n * @returns {number} The number of joints found and stored in jointArray\n * @description\n * Retrieves the IDs of all joints connected to the specified body, up to the given capacity.\n * The joint IDs are stored in the provided jointArray. The function traverses the body's\n * joint list and copies each joint's ID information including the index, world ID and revision.\n */\nexport function b2Body_GetJoints(bodyId, jointArray, capacity)\n{\n const world = b2GetWorld(bodyId.world0);\n const body = b2GetBodyFullId(world, bodyId);\n let jointKey = body.headJointKey;\n let jointCount = 0;\n\n while (jointKey !== B2_NULL_INDEX && jointCount < capacity)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = b2GetJoint(world, jointId);\n const id = new b2JointId();\n id.index1 = jointId + 1;\n id.world0 = bodyId.world0;\n id.revision = joint.revision;\n jointArray[jointCount] = id;\n jointCount += 1;\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return jointCount;\n}\n\nexport function b2ShouldBodiesCollide(world, bodyA, bodyB)\n{\n if (bodyA.type !== b2BodyType.b2_dynamicBody && bodyB.type !== b2BodyType.b2_dynamicBody)\n {\n return false;\n }\n let jointKey;\n let otherBodyId;\n\n if (bodyA.jointCount < bodyB.jointCount)\n {\n jointKey = bodyA.headJointKey;\n otherBodyId = bodyB.id;\n }\n else\n {\n jointKey = bodyB.headJointKey;\n otherBodyId = bodyA.id;\n }\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const otherEdgeIndex = edgeIndex ^ 1;\n const joint = b2GetJoint(world, jointId);\n\n if (joint.collideConnected === false && joint.edges[otherEdgeIndex].bodyId === otherBodyId)\n {\n return false;\n }\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n\n return true;\n}\n\n// PJB: recursively deep set obj 'number' properties to zero, similar to the C = { 0 };\nexport function resetProperties(obj)\n{\n const resetProperty = (item) =>\n {\n if (typeof item === 'object' && item !== null)\n {\n Object.keys(item).forEach(key =>\n {\n switch (typeof item[key])\n {\n case 'number':\n item[key] = 0;\n\n break;\n\n case 'boolean':\n item[key] = false;\n\n break;\n\n case 'string':\n item[key] = '';\n\n break;\n\n case 'object':\n if (Array.isArray(item[key]))\n {\n // item[key] = []; PJB: don't do this here, it's handled before the call in the rare instances it's needed\n }\n else if (item[key] !== null)\n {\n resetProperty(item[key]);\n }\n else\n {\n item[key] = null;\n }\n\n break;\n\n // For functions, symbols, etc., we leave them as is\n }\n });\n }\n };\n\n resetProperty(obj);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Rot, b2Transform, b2Vec2 } from './math_functions_h.js';\n\nimport { B2_NULL_INDEX } from '../core_c.js';\nimport { b2BodyType } from './types_h.js';\n\nexport class b2Body\n{\n constructor()\n {\n this.userData = null;\n this.setIndex = 0;\n this.localIndex = 0;\n this.headContactKey = 0;\n this.contactCount = 0;\n this.headShapeId = 0;\n this.shapeCount = 0;\n this.headChainId = 0;\n this.headJointKey = B2_NULL_INDEX;\n this.jointCount = 0;\n this.islandId = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.sleepThreshold = 0;\n this.sleepTime = 0;\n this.bodyMoveIndex = 0;\n this.id = B2_NULL_INDEX;\n this.type = b2BodyType.b2_staticBody;\n this.revision = 0;\n this.enableSleep = false;\n this.fixedRotation = false;\n this.isSpeedCapped = false;\n this.isMarked = false;\n this.updateBodyMass = false;\n }\n}\n\nexport class b2BodyState\n{\n constructor()\n {\n this.linearVelocity = new b2Vec2(0, 0);\n this.angularVelocity = 0;\n this.flags = 0;\n this.deltaPosition = new b2Vec2(0, 0);\n this.deltaRotation = new b2Rot(1, 0);\n }\n}\n\n// export const b2_identityBodyState = new b2BodyState();\n\nexport class b2BodySim\n{\n constructor()\n {\n this.transform = new b2Transform();\n this.center = new b2Vec2(0, 0);\n this.rotation0 = new b2Rot(1, 0);\n this.center0X = 0;\n this.center0Y = 0;\n this.localCenter = new b2Vec2(0, 0);\n this.force = new b2Vec2(0, 0);\n this.torque = 0;\n this.mass = 0;\n this.invMass = 0;\n this.inertia = 0;\n this.invInertia = 0;\n this.minExtent = 0;\n this.maxExtent = 0;\n this.linearDamping = 0;\n this.angularDamping = 0;\n this.gravityScale = 0;\n this.bodyId = 0;\n this.isFast = false;\n this.isBullet = false;\n this.isSpeedCapped = false;\n this.allowFastRotation = false;\n this.enlargeAABB = false;\n }\n\n copyTo(dst)\n {\n dst.transform = this.transform.deepClone();\n dst.center = this.center.clone();\n dst.rotation0 = this.rotation0.clone();\n dst.center0X = this.center0X;\n dst.center0Y = this.center0Y;\n dst.localCenter = this.localCenter.clone();\n dst.force = this.force.clone();\n dst.torque = this.torque;\n dst.mass = this.mass;\n dst.invMass = this.invMass;\n dst.inertia = this.inertia;\n dst.invInertia = this.invInertia;\n dst.minExtent = this.minExtent;\n dst.maxExtent = this.maxExtent;\n dst.linearDamping = this.linearDamping;\n dst.angularDamping = this.angularDamping;\n dst.gravityScale = this.gravityScale;\n dst.bodyId = this.bodyId;\n dst.isFast = this.isFast;\n dst.isBullet = this.isBullet;\n dst.isSpeedCapped = this.isSpeedCapped;\n dst.allowFastRotation = this.allowFastRotation;\n dst.enlargeAABB = this.enlargeAABB;\n }\n}\n\nexport {\n b2CreateBody, b2DestroyBody, b2GetBodyFullId, b2GetBody, b2GetBodyTransformQuick, b2GetBodyTransform, b2MakeBodyId,\n b2ShouldBodiesCollide, b2IsBodyAwake, b2GetBodySim, b2GetBodyState, b2WakeBody, b2UpdateBodyMassData,\n b2Body_IsEnabled, b2Body_GetType, b2Body_SetType, b2Body_GetUserData, b2Body_SetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetPosition, b2Body_GetRotation, b2Body_SetTransform,\n b2Body_GetMassData, b2Body_SetMassData, b2Body_GetMass,\n b2Body_GetTransform, b2Body_ApplyTorque, b2Body_GetWorldPoint, b2Body_GetWorldVector,\n b2Body_GetLinearDamping, b2Body_SetLinearDamping, b2Body_GetLinearVelocity, b2Body_SetLinearVelocity, b2Body_ApplyLinearImpulse, b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetAngularVelocity, b2Body_SetAngularVelocity, b2Body_ApplyAngularImpulse,\n b2Body_GetRotationalInertia, b2Body_GetLocalCenterOfMass, b2Body_GetWorldCenterOfMass,\n b2Body_ApplyMassFromShapes, b2Body_SetAngularDamping, b2Body_GetAngularDamping, b2Body_SetGravityScale, b2Body_GetGravityScale,\n b2Body_EnableSleep, b2Body_IsSleepEnabled, b2Body_SetSleepThreshold, b2Body_GetSleepThreshold,\n b2Body_Enable, b2Body_Disable,\n b2Body_SetFixedRotation, b2Body_IsFixedRotation,\n b2Body_GetLocalVector, b2Body_SetBullet, b2Body_IsBullet, b2Body_EnableHitEvents,\n b2Body_GetShapeCount, b2Body_GetShapes, b2Body_GetJointCount, b2Body_GetJoints,\n b2Body_ApplyForce, b2Body_SetAwake, b2Body_IsAwake, b2Body_ApplyForceToCenter,\n b2Body_GetContactCapacity, b2Body_GetContactData, b2Body_ComputeAABB,\n b2MakeSweep,\n resetProperties\n} from '../body_c.js';\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Alloc, b2Grow } from './include/allocate_h.js';\nimport { b2BodySim, b2BodyState, resetProperties } from './include/body_h.js';\n\nimport { B2_NULL_INDEX } from './include/core_h.js';\nimport { b2ContactSim } from './include/contact_h.js';\nimport { b2IslandSim } from './include/island_h.js';\nimport { b2JointSim } from './include/joint_h.js';\n\n/**\n * @namespace BlockArray\n */\n\nconst B2_INITIAL_CAPACITY = 16;\n\nexport class b2BodySimArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2BodyStateArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2ContactArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2IslandArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport class b2JointArray\n{\n constructor(capacity = 0)\n {\n this.data = [];\n this.count = 0;\n this.capacity = capacity;\n }\n}\n\nexport function b2CreateBodySimArray(capacity)\n{\n const array = new b2BodySimArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodySim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateBodyStateArray(capacity)\n{\n const array = new b2BodyStateArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2BodyState(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateContactArray(capacity)\n{\n const array = new b2ContactArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2ContactSim(); });\n\n // console.warn(\"b2CreateContactArray \" + capacity);\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateJointArray(capacity)\n{\n const array = new b2JointArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2JointSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2CreateIslandArray(capacity)\n{\n const array = new b2IslandArray(capacity);\n\n if (capacity > 0)\n {\n array.data = b2Alloc(capacity, () => { return new b2IslandSim(); });\n\n return array;\n }\n array.data = null;\n\n return array;\n}\n\nexport function b2AddBodySim(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodySim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodySim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddBodyState(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2BodyState(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2BodyState(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\n// create a b2ContactSim and add it to array, maintain count and capacity\nexport function b2AddContact(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2ContactSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n // PJB: grow quickly to avoid a bunch of these...\n const newCapacity = 8 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2ContactSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n const sim = array.data[array.count];\n resetProperties(sim);\n sim._bodyIdA = sim._bodyIdB = B2_NULL_INDEX;\n }\n\n array.count += 1;\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddJoint(array)\n{\n // array type: b2JointArray*\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2JointSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2JointSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n console.assert(array.data[array.count - 1].type !== undefined, `${new Error().stack}`);\n\n return array.data[array.count - 1];\n}\n\nexport function b2AddIsland(array)\n{\n if (array.capacity === 0)\n {\n console.assert(array.count === 0);\n array.data = b2Alloc(B2_INITIAL_CAPACITY, () => { return new b2IslandSim(); });\n array.capacity = B2_INITIAL_CAPACITY;\n array.count = 0;\n }\n else if (array.count === array.capacity)\n {\n const newCapacity = 2 * array.capacity;\n b2Grow(array.data, newCapacity, () => { return new b2IslandSim(); });\n array.capacity = newCapacity;\n }\n else\n {\n resetProperties(array.data[array.count]);\n }\n\n array.count += 1;\n array.data[array.count - 1].islandId = B2_NULL_INDEX;\n\n return array.data[array.count - 1];\n}\n\nfunction removeArrayIndex(array, index)\n{\n console.assert(0 <= index && index < array.count);\n\n if (index < array.count - 1)\n {\n const swapA = array.data[array.count - 1];\n const swapB = array.data[index];\n array.data[index] = swapA;\n array.data[array.count - 1] = swapB;\n array.count -= 1;\n\n return array.count;\n }\n array.count -= 1;\n\n return B2_NULL_INDEX;\n}\n\nexport function b2RemoveBodySim(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveBodyState(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveContact(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveJoint(array, index)\n{\n return removeArrayIndex(array, index);\n}\n\nexport function b2RemoveIsland(array, index)\n{\n return removeArrayIndex(array, index);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2DistanceInput, b2ManifoldPoint, b2Polygon } from './include/collision_h.js';\nimport {\n b2ClampFloat,\n b2Cross,\n b2DistanceSquared,\n b2Dot,\n b2DotSub,\n b2GetLengthAndNormalize,\n b2InvMulTransformsOut,\n b2LeftPerp,\n b2LengthXY,\n b2Lerp,\n b2MulAdd,\n b2MulAddOut,\n b2MulSV,\n b2Neg,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2RotateVector,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2Vec2,\n eps,\n epsSqr\n} from './include/math_functions_h.js';\nimport { b2MakeProxy, b2SegmentDistance, b2ShapeDistance } from './include/distance_h.js';\nimport { b2_linearSlop, b2_speculativeDistance } from './include/core_h.js';\n\nimport { resetProperties } from './body_c.js';\n\n/**\n * @namespace Manifold\n */\n\nconst B2_MAKE_ID = (A, B) => ((A & 0xFF) << 8) | (B & 0xFF);\n\nconst xf = new b2Transform(new b2Vec2(), new b2Rot());\nconst xf1 = new b2Transform(new b2Vec2(), new b2Rot());\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q1 = new b2Vec2();\nconst q2 = new b2Vec2();\n\nfunction b2MakeCapsule(p1, p2, radius)\n{\n const d = b2Sub(p2, p1);\n const axis = b2Normalize(d);\n const normal = b2RightPerp(axis);\n\n const shape = new b2Polygon();\n shape.vertices = [ p1, p2 ];\n shape.centroid = b2Lerp(p1, p2, 0.5);\n shape.normals = [ normal, b2Neg(normal) ];\n shape.count = 2;\n shape.radius = radius;\n\n return shape;\n}\n\n/**\n * @function b2CollideCircles\n * @description\n * Computes collision information between two circles transformed by their respective transforms.\n * @param {b2Circle} circleA - The first circle\n * @param {b2Transform} xfA - Transform for the first circle\n * @param {b2Circle} circleB - The second circle\n * @param {b2Transform} xfB - Transform for the second circle\n * @param {b2Manifold} manifold - The output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * information. If no collision is detected, returns a cleared manifold.\n */\nexport function b2CollideCircles(circleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const pointA = circleA.center;\n\n // let pointB = b2TransformPoint(xf, circleB.center);\n const pointBX = (xf.q.c * circleB.center.x - xf.q.s * circleB.center.y) + xf.p.x;\n const pointBY = (xf.q.s * circleB.center.x + xf.q.c * circleB.center.y) + xf.p.y;\n\n const sx = pointBX - pointA.x;\n const sy = pointBY - pointA.y;\n const distance = Math.sqrt(sx * sx + sy * sy);\n let normalX = 0,\n normalY = 0;\n\n if (distance >= eps)\n {\n normalX = sx / distance;\n normalY = sy / distance;\n }\n const radiusA = circleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n const cAx = pointA.x + radiusA * normalX;\n const cAy = pointA.y + radiusA * normalY;\n const cBx = pointBX + (-radiusB) * normalX;\n const cBy = pointBY + (-radiusB) * normalY;\n const contactPointAx = cAx + 0.5 * (cBx - cAx);\n const contactPointAy = cAy + 0.5 * (cBy - cAy);\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAx - xfA.q.s * contactPointAy;\n mp.anchorAY = xfA.q.s * contactPointAx + xfA.q.c * contactPointAy;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideCapsuleAndCircle\n * @description\n * Computes collision information between a capsule shape and a circle shape.\n * @param {b2Capsule} capsuleA - The capsule shape A with properties center1, center2, and radius\n * @param {b2Transform} xfA - Transform for shape A containing position (p) and rotation (q)\n * @param {b2Circle} circleB - The circle shape B with properties center and radius\n * @param {b2Transform} xfB - Transform for shape B containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output collision manifold to be populated\n * @returns {b2Manifold} The populated collision manifold containing contact points,\n * normal, separation, and other collision data\n */\nexport function b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the capsule.\n const pB = b2TransformPoint(xf, circleB.center);\n\n // Compute closest point\n const p1 = capsuleA.center1;\n const p2 = capsuleA.center2;\n\n const e = b2Sub(p2, p1);\n\n // dot(p - pA, e) = 0\n // dot(p - (p1 + s1 * e), e) = 0\n // s1 = dot(p - p1, e)\n let pA;\n const s1 = b2Dot(b2Sub(pB, p1), e);\n const s2 = b2Dot(b2Sub(p2, pB), e);\n\n if (s1 < 0.0)\n {\n // p1 region\n pA = p1;\n }\n else if (s2 < 0.0)\n {\n // p2 region\n pA = p2;\n }\n else\n {\n // circle colliding with segment interior\n const s = s1 / b2Dot(e, e);\n pA = b2MulAdd(p1, s, e);\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radiusA = capsuleA.radius;\n const radiusB = circleB.radius;\n const separation = distance - radiusA - radiusB;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = b2MulAdd(pA, radiusA, normal);\n const cB = b2MulAdd(pB, -radiusB, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\nconst c = new b2Vec2();\n\n/**\n * @function b2CollidePolygonAndCircle\n * @description\n * Computes collision information between a polygon and a circle.\n * @param {b2Polygon} polygonA - The polygon shape\n * @param {b2Transform} xfA - Transform for polygon A\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circle B\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {b2Manifold} The collision manifold containing contact points, normal, and separation\n * @note The manifold is cleared and returned if no collision is detected.\n * The function handles three cases:\n * 1. Circle center closest to polygon vertex 1\n * 2. Circle center closest to polygon vertex 2\n * 3. Circle center closest to polygon edge\n */\nexport function b2CollidePolygonAndCircle(polygonA, xfA, circleB, xfB, manifold)\n{\n const speculativeDistance = b2_speculativeDistance;\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle position in the frame of the polygon.\n b2TransformPointOut(xf, circleB.center, c);\n const radiusA = polygonA.radius;\n const radiusB = circleB.radius;\n const radius = radiusA + radiusB;\n\n // Find the min separating edge.\n let normalIndex = 0;\n let separation = -Number.MAX_VALUE;\n const vertexCount = polygonA.count;\n const vertices = polygonA.vertices;\n const normals = polygonA.normals;\n\n for (let i = 0; i < vertexCount; ++i)\n {\n // let s = b2Dot(normals[i], b2Sub(c, vertices[i]));\n const s = normals[i].x * (c.x - vertices[i].x) + normals[i].y * (c.y - vertices[i].y);\n\n if (s > separation)\n {\n separation = s;\n normalIndex = i;\n }\n }\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n // Vertices of the reference edge.\n const vertIndex1 = normalIndex;\n const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\n const v1 = vertices[vertIndex1];\n const v2 = vertices[vertIndex2];\n\n // Compute barycentric coordinates\n const u1 = (c.x - v1.x) * (v2.x - v1.x) + (c.y - v1.y) * (v2.y - v1.y);\n const u2 = (c.x - v2.x) * (v1.x - v2.x) + (c.y - v2.y) * (v1.y - v2.y);\n\n if (u1 < 0.0 && separation > eps)\n {\n // Circle center is closest to v1 and safely outside the polygon\n const x = c.x - v1.x;\n const y = c.y - v1.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v1.x) * normalX + (c.y - v1.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v1.x + radiusA * normalX;\n const cAY = v1.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else if (u2 < 0.0 && separation > eps)\n {\n // Circle center is closest to v2 and safely outside the polygon\n const x = c.x - v2.x;\n const y = c.y - v2.y;\n const length = Math.sqrt(x * x + y * y);\n let normalX = 0,\n normalY = 0;\n\n if (length > eps)\n {\n const invLength = 1 / length;\n normalX = x * invLength;\n normalY = y * invLength;\n }\n\n separation = (c.x - v2.x) * normalX + (c.y - v2.y) * normalY;\n\n if (separation > radius + speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cAX = v2.x + radiusA * normalX;\n const cAY = v2.y + radiusA * normalY;\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n const contactPointAX = 0.5 * (cAX + cBX);\n const contactPointAY = 0.5 * (cAY + cBY);\n\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = (cBX - cAX) * normalX + (cBY - cAY) * normalY;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n else\n {\n // Circle center is between v1 and v2. Center may be inside polygon\n const normalX = normals[normalIndex].x;\n const normalY = normals[normalIndex].y;\n manifold.normalX = xfA.q.c * normalX - xfA.q.s * normalY;\n manifold.normalY = xfA.q.s * normalX + xfA.q.c * normalY;\n\n // cA is the projection of the circle center onto to the reference edge\n const d = radiusA - ((c.x - v1.x) * normalX + (c.y - v1.y) * normalY);\n const cAX = c.x + d * normalX;\n const cAY = c.y + d * normalY;\n\n // cB is the deepest point on the circle with respect to the reference edge\n const cBX = c.x - radiusB * normalX;\n const cBY = c.y - radiusB * normalY;\n\n // contactPointA is the midpoint between cA and cB\n const contactPointAX = (cAX + cBX) * 0.5;\n const contactPointAY = (cAY + cBY) * 0.5;\n\n // The contact point is the midpoint in world space\n const mp = manifold.points[0];\n mp.anchorAX = xfA.q.c * contactPointAX - xfA.q.s * contactPointAY;\n mp.anchorAY = xfA.q.s * contactPointAX + xfA.q.c * contactPointAY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation - radius;\n mp.id = 0;\n manifold.pointCount = 1;\n }\n\n return manifold;\n}\n\n// PJB - with allocation avoidance edits\n\n/**\n * @function b2CollideCapsules\n * @description\n * Computes the collision manifold between two capsule shapes in 2D space.\n * A capsule is defined by two endpoints and a radius.\n * @param {b2Capsule} capsuleA - The first capsule shape\n * @param {b2Transform} xfA - Transform for the first capsule\n * @param {b2Capsule} capsuleB - The second capsule shape\n * @param {b2Transform} xfB - Transform for the second capsule\n * @param {b2Manifold} manifold - Output collision manifold\n * @returns {void} Modifies the manifold parameter with collision data:\n * - normalX/Y: Collision normal vector\n * - pointCount: Number of contact points (0-2)\n * - points[]: Contact point data including:\n * - anchorA/B: Contact points in local coordinates\n * - separation: Penetration depth\n * - id: Contact ID\n */\nexport function b2CollideCapsules(capsuleA, xfA, capsuleB, xfB, manifold)\n{\n const origin = capsuleA.center1;\n\n // let sfA = {\n // p: b2Add(xfA.p, b2RotateVector(xfA.q, origin)),\n // q: xfA.q\n // };\n b2MulAddOut(xfA.p, 1, b2RotateVector(xfA.q, origin), xf1.p);\n xf1.q = xfA.q;\n b2InvMulTransformsOut(xf1, xfB, xf);\n\n // let p1 = new b2Vec2(0, 0);\n p1.x = 0;\n p1.y = 0;\n\n // let q1 = b2Sub(capsuleA.center2, origin);\n q1.x = capsuleA.center2.x - origin.x;\n q1.y = capsuleA.center2.y - origin.y;\n\n // let p2 = b2TransformPoint(xf, capsuleB.center1);\n b2TransformPointOut(xf, capsuleB.center1, p2);\n\n // let q2 = b2TransformPoint(xf, capsuleB.center2);\n b2TransformPointOut(xf, capsuleB.center2, q2);\n const d1X = q1.x;\n const d1Y = q1.y;\n const d2X = q2.x - p2.x;\n const d2Y = q2.y - p2.y;\n const dd1 = d1X * d1X + d1Y * d1Y;\n const dd2 = d2X * d2X + d2Y * d2Y;\n console.assert(dd1 > epsSqr && dd2 > epsSqr, `dd1=${dd1} dd2=${dd2} (both should be > epsilon squared)`);\n const rX = p1.x - p2.x;\n const rY = p1.y - p2.y;\n const rd1 = rX * d1X + rY * d1Y;\n const rd2 = rX * d2X + rY * d2Y;\n const d12 = d1X * d2X + d1Y * d2Y;\n const denom = dd1 * dd2 - d12 * d12;\n let f1 = 0.0;\n\n if (denom !== 0.0)\n {\n f1 = b2ClampFloat((d12 * rd2 - rd1 * dd2) / denom, 0.0, 1.0);\n }\n let f2 = (d12 * f1 + rd2) / dd2;\n\n if (f2 < 0.0)\n {\n f2 = 0.0;\n f1 = b2ClampFloat(-rd1 / dd1, 0.0, 1.0);\n }\n else if (f2 > 1.0)\n {\n f2 = 1.0;\n f1 = b2ClampFloat((d12 - rd1) / dd1, 0.0, 1.0);\n }\n\n // let closest1 = b2MulAdd(p1, f1, d1);\n const closest1 = { x: p1.x + f1 * d1X, y: p1.y + f1 * d1Y };\n\n // let closest2 = b2MulAdd(p2, f2, d2);\n const closest2 = { x: p2.x + f2 * d2X, y: p2.y + f2 * d2Y };\n const distanceSquared = b2DistanceSquared(closest1, closest2);\n const radiusA = capsuleA.radius;\n const radiusB = capsuleB.radius;\n const radius = radiusA + radiusB;\n const maxDistance = radius + b2_speculativeDistance;\n\n if (distanceSquared > maxDistance * maxDistance)\n {\n resetProperties(manifold);\n\n return;\n }\n const distance = Math.sqrt(distanceSquared);\n const length1 = b2LengthXY(d1X, d1Y);\n const u1X = d1X * 1.0 / length1;\n const u1Y = d1Y * 1.0 / length1;\n const length2 = b2LengthXY(d2X, d2Y);\n const u2X = d2X * 1.0 / length2;\n const u2Y = d2Y * 1.0 / length2;\n\n // let fp2 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, u1n);\n const fp2 = (p2.x - p1.x) * u1X + (p2.y - p1.y) * u1Y;\n const fq2 = (q2.x - p1.x) * u1X + (q2.y - p1.y) * u1Y;\n const outsideA = (fp2 <= 0.0 && fq2 <= 0.0) || (fp2 >= length1 && fq2 >= length1);\n\n // let fp1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, u2n);\n // let fq1 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, u2n);\n const fp1 = (p1.x - p2.x) * u1X + (p1.y - p2.y) * u2Y;\n const fq1 = (q1.x - p2.x) * u1X + (q1.y - p2.y) * u2Y;\n const outsideB = (fp1 <= 0.0 && fq1 <= 0.0) || (fp1 >= length2 && fq1 >= length2);\n\n manifold.pointCount = 0;\n \n if (outsideA === false && outsideB === false)\n {\n let normalAX, normalAY, separationA;\n\n {\n // normal = b2LeftPerp(u1n);\n normalAX = -u1Y;\n normalAY = u1X;\n\n // let ss1 = b2Dot({ x: p2.x - p1.x, y: p2.y - p1.y }, normalA);\n // let ss2 = b2Dot({ x: q2.x - p1.x, y: q2.y - p1.y }, normalA);\n const ss1 = (p2.x - p1.x) * normalAX + (p2.y - p1.y) * normalAY;\n const ss2 = (q2.x - p1.x) * normalAX + (q2.y - p1.y) * normalAY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationA = s1p;\n }\n else\n {\n separationA = s1n;\n\n // normalA = { x: -normalA.x, y: -normalA.y };\n normalAX = -normalAX;\n normalAY = -normalAY;\n }\n }\n let normalBX, normalBY, separationB;\n\n {\n // normalB = b2LeftPerp(u2n);\n normalBX = -u2Y;\n normalBY = u2X;\n\n // let ss1 = b2Dot({ x: p1.x - p2.x, y: p1.y - p2.y }, normalB);\n // let ss2 = b2Dot({ x: q1.x - p2.x, y: q1.y - p2.y }, normalB);\n const ss1 = (p1.x - p2.x) * normalBX + (p1.y - p2.y) * normalBY;\n const ss2 = (q1.x - p2.x) * normalBX + (q1.y - p2.y) * normalBY;\n const s1p = Math.min(ss1, ss2);\n const s1n = Math.max(-ss1, -ss2);\n\n if (s1p > s1n)\n {\n separationB = s1p;\n }\n else\n {\n separationB = s1n;\n\n // normalB = { x: -normalB.x, y: -normalB.y };\n normalBX = -normalBX;\n normalBY = -normalBY;\n }\n }\n\n if (separationA >= separationB)\n {\n manifold.normalX = normalAX;\n manifold.normalY = normalAY;\n let cpX = p2.x;\n let cpY = p2.y;\n let cqX = q2.x;\n let cqY = q2.y;\n\n if (fp2 < 0.0 && fq2 > 0.0)\n {\n const t = (0.0 - fp2) / (fq2 - fp2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 < 0.0 && fp2 > 0.0)\n {\n const t = (0.0 - fq2) / (fp2 - fq2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n if (fp2 > length1 && fq2 < length1)\n {\n const t = (fp2 - length1) / (fp2 - fq2);\n cpX = p2.x + t * (q2.x - p2.x);\n cpY = p2.y + t * (q2.y - p2.y);\n }\n else if (fq2 > length1 && fp2 < length1)\n {\n const t = (fq2 - length1) / (fq2 - fp2);\n cqX = q2.x + t * (p2.x - q2.x);\n cqY = q2.y + t * (p2.y - q2.y);\n }\n\n // let sp = b2Dot({ x: cpX - p1.x, y: cpY - p1.y }, { x: normalAX, y: normalAY });\n // let sq = b2Dot({ x: cqX - p1.x, y: cqY - p1.y }, { x: normalAX, y: normalAY });\n const sp = (cpX - p1.x) * normalAX + (cpY - p1.y) * normalAY;\n const sq = (cqX - p1.x) * normalAX + (cqY - p1.y) * normalAY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusA - radiusB - sp);\n manifold.points[0].anchorAX = cpX + s * normalAX;\n manifold.points[0].anchorAY = cpY + s * normalAY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n s = 0.5 * (radiusA - radiusB - sq);\n manifold.points[1].anchorAX = cqX + s * normalAX;\n manifold.points[1].anchorAY = cqY + s * normalAY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(0, 1);\n manifold.pointCount = 2;\n }\n }\n else\n {\n manifold.normalX = -normalBX;\n manifold.normalY = -normalBY;\n let cpX = p1.x;\n let cpY = p1.y;\n let cqX = q1.x;\n let cqY = q1.y;\n\n if (fp1 < 0.0 && fq1 > 0.0)\n {\n const t = (0.0 - fp1) / (fq1 - fp1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 < 0.0 && fp1 > 0.0)\n {\n const t = (0.0 - fq1) / (fp1 - fq1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n\n if (fp1 > length2 && fq1 < length2)\n {\n const t = (fp1 - length2) / (fp1 - fq1);\n cpX = p1.x + t * (q1.x - p1.x);\n cpY = p1.y + t * (q1.y - p1.y);\n }\n else if (fq1 > length2 && fp1 < length2)\n {\n const t = (fq1 - length2) / (fq1 - fp1);\n cqX = q1.x + t * (p1.x - q1.x);\n cqY = q1.y + t * (p1.y - q1.y);\n }\n const sp = (cpX - p2.x) * normalBX + (cpY - p2.y) * normalBY;\n const sq = (cqX - p2.x) * normalBX + (cqY - p2.y) * normalBY;\n\n if (sp <= distance + b2_linearSlop || sq <= distance + b2_linearSlop)\n {\n let s = 0.5 * (radiusB - radiusA - sp);\n manifold.points[0].anchorAX = cpX + s * normalBX;\n manifold.points[0].anchorAY = cpY + s * normalBY;\n manifold.points[0].separation = sp - radius;\n manifold.points[0].id = B2_MAKE_ID(0, 0);\n \n s = 0.5 * (radiusB - radiusA - sq);\n manifold.points[1].anchorAX = cqX + s * normalBX;\n manifold.points[1].anchorAY = cqY + s * normalBY;\n manifold.points[1].separation = sq - radius;\n manifold.points[1].id = B2_MAKE_ID(1, 0);\n manifold.pointCount = 2;\n }\n }\n }\n\n if (manifold.pointCount === 0)\n {\n let normalX = closest2.x - closest1.x;\n let normalY = closest2.y - closest1.y;\n const lengthSq = normalX * normalX + normalY * normalY;\n\n if (lengthSq > epsSqr)\n {\n const length = Math.sqrt(lengthSq);\n normalX /= length;\n normalY /= length;\n }\n else\n {\n // const leftPerp = b2LeftPerp(u1);\n normalX = -u1Y; // leftPerp.x;\n normalY = u1X; // leftPerp.y;\n }\n const c1X = closest1.x + radiusA * normalX;\n const c1Y = closest1.y + radiusA * normalY;\n const c2X = closest2.x - radiusB * normalX;\n const c2Y = closest2.y - radiusB * normalY;\n const i1 = f1 === 0.0 ? 0 : 1;\n const i2 = f2 === 0.0 ? 0 : 1;\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n manifold.points[0].anchorAX = (c1X + c2X) * 0.5;\n manifold.points[0].anchorAY = (c1Y + c2Y) * 0.5;\n manifold.points[0].separation = Math.sqrt(distanceSquared) - radius;\n manifold.points[0].id = B2_MAKE_ID(i1, i2);\n manifold.pointCount = 1;\n }\n\n if (manifold.pointCount > 0)\n {\n const rotatedNormalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n const rotatedNormalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n manifold.normalX = rotatedNormalX;\n manifold.normalY = rotatedNormalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n const vx = mp.anchorAX + origin.x;\n const vy = mp.anchorAY + origin.y;\n const rotatedVecX = xfA.q.c * vx - xfA.q.s * vy;\n const rotatedVecY = xfA.q.s * vx + xfA.q.c * vy;\n mp.anchorAX = rotatedVecX;\n mp.anchorAY = rotatedVecY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return;\n}\n\n\n// initialized here, used as a static variable to avoid allocating memory on every \n// call to b2CollideSegmentAndCapsule\nconst constCapsule = new b2Capsule();\n\n/**\n * @function b2CollideSegmentAndCapsule\n * @summary Computes collision between a line segment and a capsule.\n * @param {b2Segment} segmentA - A line segment defined by two points (point1, point2)\n * @param {b2Transform} xfA - Transform for segmentA containing position and rotation\n * @param {b2Capsule} capsuleB - A capsule shape defined by two points and a radius\n * @param {b2Transform} xfB - Transform for capsuleB containing position and rotation\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n * @description\n * Converts the segment to a zero-radius capsule and delegates to b2CollideCapsules\n * for the actual collision computation.\n */\nexport function b2CollideSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, manifold)\n{\n constCapsule.center1 = segmentA.point1;\n constCapsule.center2 = segmentA.point2;\n constCapsule.radius = 0;\n\n return b2CollideCapsules(constCapsule, xfA, capsuleB, xfB, manifold);\n}\n\n/**\n * @function b2CollidePolygonAndCapsule\n * @description\n * Computes collision manifold between a polygon and a capsule by converting the capsule\n * to a polygon and using polygon-polygon collision detection.\n * @param {b2Polygon} polygonA - The first collision shape (polygon)\n * @param {b2Transform} xfA - Transform for polygon A, containing position and rotation\n * @param {b2Capsule} capsuleB - The second collision shape (capsule) defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsule B, containing position and rotation\n * @param {b2Manifold} manifold - The output collision manifold to be populated\n * @returns {b2Manifold} The collision manifold containing contact points and normal\n */\nexport function b2CollidePolygonAndCapsule(polygonA, xfA, capsuleB, xfB, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollidePolygons(polygonA, xfA, polyB, xfB, manifold);\n}\n\n// Polygon clipper used to compute contact points when there are potentially two contact points.\nfunction b2ClipPolygons(polyA, polyB, edgeA, edgeB, flip, manifold)\n{\n // reference polygon\n let poly1, i11, i12;\n\n // incident polygon\n let poly2, i21, i22;\n\n if (flip)\n {\n poly1 = polyB;\n poly2 = polyA;\n i11 = edgeB;\n i12 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n i21 = edgeA;\n i22 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n }\n else\n {\n poly1 = polyA;\n poly2 = polyB;\n i11 = edgeA;\n i12 = edgeA + 1 < polyA.count ? edgeA + 1 : 0;\n i21 = edgeB;\n i22 = edgeB + 1 < polyB.count ? edgeB + 1 : 0;\n }\n\n const normal = poly1.normals[i11];\n\n // Reference edge vertices\n const v11 = poly1.vertices[i11];\n const v12 = poly1.vertices[i12];\n\n // Incident edge vertices\n const v21 = poly2.vertices[i21];\n const v22 = poly2.vertices[i22];\n\n // const tangent = b2CrossSV(1.0, normal);\n const tangentX = -1.0 * normal.y;\n const tangentY = 1.0 * normal.x;\n\n const lower1 = 0.0;\n\n // const upper1 = b2Dot(b2Sub(v12, v11), tangent);\n let subX = v12.x - v11.x;\n let subY = v12.y - v11.y;\n const upper1 = subX * tangentX + subY * tangentY;\n\n // Incident edge points opposite of tangent due to CCW winding\n // const upper2 = b2Dot(b2Sub(v21, v11), tangent);\n subX = v21.x - v11.x;\n subY = v21.y - v11.y;\n const upper2 = subX * tangentX + subY * tangentY;\n\n // const lower2 = b2Dot(b2Sub(v22, v11), tangent);\n subX = v22.x - v11.x;\n subY = v22.y - v11.y;\n const lower2 = subX * tangentX + subY * tangentY;\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(v22, v21, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = v22;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(v22, v21, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = v21;\n }\n\n // const separationLower = b2Dot(b2Sub(vLower, v11), normal);\n // const separationUpper = b2Dot(b2Sub(vUpper, v11), normal);\n const separationLower = b2DotSub(vLower, v11, normal);\n const separationUpper = b2DotSub(vUpper, v11, normal);\n\n const r1 = poly1.radius;\n const r2 = poly2.radius;\n\n // Put contact points at midpoint, accounting for radii\n // vLower = b2MulAdd(vLower, 0.5 * (r1 - r2 - separationLower), normal);\n // vUpper = b2MulAdd(vUpper, 0.5 * (r1 - r2 - separationUpper), normal);\n b2MulAddOut(vLower, 0.5 * (r1 - r2 - separationLower), normal, p1);\n b2MulAddOut(vUpper, 0.5 * (r1 - r2 - separationUpper), normal, p2);\n\n const radius = r1 + r2;\n\n if (flip === false)\n {\n manifold.normalX = normal.x;\n manifold.normalY = normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n\n mp = manifold.points[1];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.pointCount = 2;\n }\n else\n {\n // manifold.normal = b2Neg(normal);\n manifold.normalX = -normal.x;\n manifold.normalY = -normal.y;\n let mp = manifold.points[0];\n mp.anchorAX = p2.x;\n mp.anchorAY = p2.y;\n mp.separation = separationUpper - radius;\n mp.id = B2_MAKE_ID(i21, i12);\n\n mp = manifold.points[1];\n mp.anchorAX = p1.x;\n mp.anchorAY = p1.y;\n mp.separation = separationLower - radius;\n mp.id = B2_MAKE_ID(i22, i11);\n manifold.pointCount = 2;\n }\n\n return manifold;\n}\n\n// Find the max separation between poly1 and poly2 using edge normals from poly1.\nfunction b2FindMaxSeparation(poly1, poly2)\n{\n const count1 = poly1.count;\n const count2 = poly2.count;\n const n1s = poly1.normals;\n const v1s = poly1.vertices;\n const v2s = poly2.vertices;\n\n let bestIndex = 0;\n let maxSeparation = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < count1; ++i)\n {\n // Get poly1 normal in frame2.\n const n = n1s[i];\n const vx = v1s[i].x,\n vy = v1s[i].y;\n\n // Find the deepest point for normal i.\n let si = Number.POSITIVE_INFINITY;\n\n for (let j = 0; j < count2; ++j)\n {\n const dx = v2s[j].x - vx;\n const dy = v2s[j].y - vy;\n const sij = n.x * dx + n.y * dy;\n\n // const sij = b2Dot(n, b2Sub(v2s[j], v1));\n if (sij < si)\n {\n si = sij;\n }\n }\n\n if (si > maxSeparation)\n {\n maxSeparation = si;\n bestIndex = i;\n }\n }\n\n return { edgeIndex: bestIndex, maxSeparation: maxSeparation }; // PJB = the C version returns float maxSeparation here and bestIndex through *edgeIndex parameter\n}\n\n// Due to speculation, every polygon is rounded\n// Algorithm:\n//\n// compute edge separation using the separating axis test (SAT)\n// if (separation > speculation_distance)\n// return\n// find reference and incident edge\n// if separation >= 0.1f * b2_linearSlop\n// compute closest points between reference and incident edge\n// if vertices are closest\n// single vertex-vertex contact\n// else\n// clip edges\n// end\n// else\n// clip edges\n// end\n\nconst localPolyA = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst localPolyB = new b2Polygon(B2_MAX_POLYGON_VERTICES);\nconst p = new b2Vec2();\nconst sfA = new b2Transform();\n\n/**\n * @function b2CollidePolygons\n * @description\n * Computes collision manifold between two polygons using their transforms.\n * @param {b2Polygon} polygonA - First polygon\n * @param {b2Transform} xfA - Transform for first polygon containing position (p) and rotation (q)\n * @param {b2Polygon} polygonB - Second polygon\n * @param {b2Transform} xfB - Transform for second polygon containing position (p) and rotation (q)\n * @param {b2Manifold} manifold - Output manifold to store collision data\n * @returns {b2Manifold} The collision manifold containing contact points, normal and separation\n * @description\n * Detects collision between two polygons and generates contact information.\n * Transforms the polygons into a common frame, finds the separating axes,\n * and generates contact points. The manifold includes contact points with\n * anchor positions, separation distance, contact IDs and collision normal.\n */\nexport function b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold)\n{\n const originX = polygonA.vertices[0].x;\n const originY = polygonA.vertices[0].y;\n\n p.x = xfA.p.x + (xfA.q.c * originX - xfA.q.s * originY);\n p.y = xfA.p.y + (xfA.q.s * originX + xfA.q.c * originY);\n sfA.p = p;\n sfA.q = xfA.q;\n b2InvMulTransformsOut(sfA, xfB, xf);\n\n // Shift polyA to origin, retain rotation\n localPolyA.centroid = null;\n \n localPolyA.count = polygonA.count;\n localPolyA.radius = polygonA.radius;\n localPolyA.vertices[0].x = 0;\n localPolyA.vertices[0].y = 0;\n localPolyA.normals[0].x = polygonA.normals[0].x;\n localPolyA.normals[0].y = polygonA.normals[0].y;\n\n for (let i = 1; i < localPolyA.count; ++i)\n {\n const v = localPolyA.vertices[i];\n v.x = polygonA.vertices[i].x - originX;\n v.y = polygonA.vertices[i].y - originY;\n const n = localPolyA.normals[i];\n n.x = polygonA.normals[i].x;\n n.y = polygonA.normals[i].y;\n }\n\n // Put polyB in polyA's frame to reduce round-off error\n localPolyA.centroid = null;\n\n localPolyB.count = polygonB.count;\n localPolyB.radius = polygonB.radius;\n\n for (let i = 0; i < localPolyB.count; ++i)\n {\n const v = localPolyB.vertices[i];\n const p = polygonB.vertices[i];\n v.x = (xf.q.c * p.x - xf.q.s * p.y) + xf.p.x;\n v.y = (xf.q.s * p.x + xf.q.c * p.y) + xf.p.y;\n const n = localPolyB.normals[i];\n n.x = xf.q.c * polygonB.normals[i].x - xf.q.s * polygonB.normals[i].y;\n n.y = xf.q.s * polygonB.normals[i].x + xf.q.c * polygonB.normals[i].y;\n }\n\n const ret1 = b2FindMaxSeparation(localPolyA, localPolyB);\n let edgeA = ret1.edgeIndex;\n const separationA = ret1.maxSeparation;\n\n const ret2 = b2FindMaxSeparation(localPolyB, localPolyA);\n let edgeB = ret2.edgeIndex;\n const separationB = ret2.maxSeparation;\n\n const radius = localPolyA.radius + localPolyB.radius;\n\n if (separationA > b2_speculativeDistance + radius || separationB > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n\n // Find incident edge\n let flip;\n\n if (separationA >= separationB)\n {\n flip = false;\n\n const searchDirection = localPolyA.normals[edgeA];\n\n // Find the incident edge on polyB\n const count = localPolyB.count;\n const normals = localPolyB.normals;\n edgeB = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeB = i;\n }\n }\n }\n else\n {\n flip = true;\n\n const searchDirection = localPolyB.normals[edgeB];\n\n // Find the incident edge on polyA\n const count = localPolyA.count;\n const normals = localPolyA.normals;\n edgeA = 0;\n let minDot = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const dot = searchDirection.x * normals[i].x + searchDirection.y * normals[i].y;\n\n if (dot < minDot)\n {\n minDot = dot;\n edgeA = i;\n }\n }\n }\n\n // let manifold = new b2Manifold();\n\n // Using slop here to ensure vertex-vertex normal vectors can be safely normalized\n // todo this means edge clipping needs to handle slightly non-overlapping edges.\n if (separationA > 0.1 * b2_linearSlop || separationB > 0.1 * b2_linearSlop)\n {\n // Polygons are disjoint. Find closest points between reference edge and incident edge\n // Reference edge on polygon A\n const i11 = edgeA;\n const i12 = edgeA + 1 < localPolyA.count ? edgeA + 1 : 0;\n const i21 = edgeB;\n const i22 = edgeB + 1 < localPolyB.count ? edgeB + 1 : 0;\n\n const v11 = localPolyA.vertices[i11];\n const v12 = localPolyA.vertices[i12];\n const v21 = localPolyB.vertices[i21];\n const v22 = localPolyB.vertices[i22];\n\n const result = b2SegmentDistance(v11.x, v11.y, v12.x, v12.y, v21.x, v21.y, v22.x, v22.y);\n\n // return {\n // fraction1,\n // fraction2,\n // distanceSquared\n // };\n\n if (result.fraction1 === 0.0 && result.fraction2 === 0.0)\n {\n // v11 - v21\n let normalX = v21.x - v11.x;\n let normalY = v21.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n // manifold.normal = new b2Vec2(normalX, normalY);\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = manifold.points[0];\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i21);\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 0.0 && result.fraction2 === 1.0)\n {\n // v11 - v22\n let normalX = v22.x - v11.x;\n let normalY = v22.y - v11.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v11.x + localPolyA.radius * normalX;\n const c1Y = v11.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i11, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 0.0)\n {\n // v12 - v21\n let normalX = v21.x - v12.x;\n let normalY = v21.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v21.x - localPolyB.radius * normalX;\n const c2Y = v21.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i21);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else if (result.fraction1 === 1.0 && result.fraction2 === 1.0)\n {\n // v12 - v22\n let normalX = v22.x - v12.x;\n let normalY = v22.y - v12.y;\n console.assert(result.distanceSquared > 0.0);\n const distance = Math.sqrt(result.distanceSquared);\n\n if (distance > b2_speculativeDistance + radius)\n {\n return manifold.clear();\n }\n const invDistance = 1.0 / distance;\n normalX *= invDistance;\n normalY *= invDistance;\n\n const c1X = v12.x + localPolyA.radius * normalX;\n const c1Y = v12.y + localPolyA.radius * normalY;\n const c2X = v22.x - localPolyB.radius * normalX;\n const c2Y = v22.y - localPolyB.radius * normalY;\n\n manifold.normalX = normalX;\n manifold.normalY = normalY;\n const mp = new b2ManifoldPoint();\n mp.anchorAX = (c1X + c2X) * 0.5;\n mp.anchorAY = (c1Y + c2Y) * 0.5;\n mp.separation = distance - radius;\n mp.id = B2_MAKE_ID(i12, i22);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n }\n else\n {\n // Edge region\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n }\n else\n {\n // Polygons overlap\n b2ClipPolygons(localPolyA, localPolyB, edgeA, edgeB, flip, manifold);\n }\n\n // Convert manifold to world space\n if (manifold.pointCount > 0)\n {\n const tmpx = manifold.normalX;\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * tmpx + xfA.q.c * manifold.normalY;\n\n for (let i = 0; i < manifold.pointCount; ++i)\n {\n const mp = manifold.points[i];\n\n const addX = mp.anchorAX + originX;\n const addY = mp.anchorAY + originY;\n mp.anchorAX = xfA.q.c * addX - xfA.q.s * addY;\n mp.anchorAY = xfA.q.s * addX + xfA.q.c * addY;\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n }\n }\n\n return manifold;\n}\n\n/**\n * @function b2CollideSegmentAndCircle\n * @description\n * Computes collision detection between a line segment and a circle by converting\n * the segment to a zero-radius capsule and using capsule-circle collision.\n * @param {b2Segment} segmentA - The line segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Circle} circleB - The circle shape\n * @param {b2Transform} xfB - Transform for circleB\n * @param {b2Manifold} manifold - The collision manifold to populate\n * @returns {b2Manifold} The collision manifold containing contact information\n */\nexport function b2CollideSegmentAndCircle(segmentA, xfA, circleB, xfB, manifold)\n{\n const capsuleA = new b2Capsule();\n capsuleA.center1 = segmentA.point1;\n capsuleA.center2 = segmentA.point2;\n capsuleA.radius = 0.0;\n\n return b2CollideCapsuleAndCircle(capsuleA, xfA, circleB, xfB, manifold);\n}\n\n/**\n * @function b2CollideSegmentAndPolygon\n * @description\n * Computes collision manifold between a line segment and a polygon by converting\n * the segment into a zero-width capsule and using polygon collision detection.\n * @param {b2Segment} segmentA - The line segment\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Polygon} polygonB - The polygon to test collision against\n * @param {b2Transform} xfB - Transform for polygonB\n * @param {b2Manifold} manifold - The manifold to populate with collision data\n * @returns {b2Manifold} Collision manifold containing contact points and normal\n */\nexport function b2CollideSegmentAndPolygon(segmentA, xfA, polygonB, xfB, manifold)\n{\n const polygonA = b2MakeCapsule(segmentA.point1, segmentA.point2, 0.0);\n\n return b2CollidePolygons(polygonA, xfA, polygonB, xfB, manifold);\n}\n\n// Assuming similar structures exist for b2Manifold, b2Transform, b2ChainSegment, b2Circle, etc.\n/**\n * @function b2CollideChainSegmentAndCircle\n * @description\n * Computes collision detection between a chain segment and a circle.\n * @param {Object} chainSegmentA - A chain segment with properties segment (containing point1 and point2) and ghost points (ghost1, ghost2)\n * @param {Object} xfA - Transform for chain segment containing position (p) and rotation (q)\n * @param {Object} circleB - Circle object with center point and radius\n * @param {Object} xfB - Transform for circle containing position (p) and rotation (q)\n * @param {Object} manifold - Contact manifold to store collision results\n * @returns {Object} The manifold object containing collision data:\n * - normalX/Y: collision normal in world coordinates\n * - points: array with contact point data including:\n * - anchorA/B: contact points in local coordinates\n * - point: contact point in world coordinates\n * - separation: distance between shapes\n * - id: contact ID\n * - pointCount: number of contact points\n */\nexport function b2CollideChainSegmentAndCircle(chainSegmentA, xfA, circleB, xfB, manifold)\n{\n // let manifold = new b2Manifold();\n\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n // Compute circle in frame of segment\n const pB = b2TransformPoint(xf, circleB.center);\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n const e = b2Sub(p2, p1);\n\n // Normal points to the right\n const offset = b2Dot(b2RightPerp(e), b2Sub(pB, p1));\n\n if (offset < 0.0)\n {\n // collision is one-sided\n return manifold.clear();\n }\n\n // Barycentric coordinates\n const u = b2Dot(e, b2Sub(p2, pB));\n const v = b2Dot(e, b2Sub(pB, p1));\n\n let pA;\n\n if (v <= 0.0)\n {\n // Behind point1?\n // Is pB in the Voronoi region of the previous edge?\n const prevEdge = b2Sub(p1, chainSegmentA.ghost1);\n const uPrev = b2Dot(prevEdge, b2Sub(pB, p1));\n\n if (uPrev <= 0.0)\n {\n return manifold.clear();\n }\n\n pA = p1;\n }\n else if (u <= 0.0)\n {\n // Ahead of point2?\n const nextEdge = b2Sub(chainSegmentA.ghost2, p2);\n const vNext = b2Dot(nextEdge, b2Sub(pB, p2));\n\n // Is pB in the Voronoi region of the next edge?\n if (vNext > 0.0)\n {\n return manifold.clear();\n }\n\n pA = p2;\n }\n else\n {\n const ee = b2Dot(e, e);\n pA = new b2Vec2(u * p1.x + v * p2.x, u * p1.y + v * p2.y);\n pA = ee > 0.0 ? b2MulSV(1.0 / ee, pA) : p1;\n }\n\n const res = b2GetLengthAndNormalize(b2Sub(pB, pA));\n const distance = res.length;\n const normal = res.normal;\n\n const radius = circleB.radius;\n const separation = distance - radius;\n\n if (separation > b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const cA = pA;\n const cB = b2MulAdd(pB, -radius, normal);\n const contactPointA = b2Lerp(cA, cB, 0.5);\n\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n const mp = manifold.points[0];\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * contactPointA.x - xfA.q.s * contactPointA.y;\n mp.anchorAY = xfA.q.s * contactPointA.x + xfA.q.c * contactPointA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = separation;\n mp.id = 0;\n manifold.pointCount = 1;\n\n return manifold;\n}\n\n/**\n * @function b2CollideChainSegmentAndCapsule\n * @description\n * Computes collision between a chain segment and a capsule by converting the capsule\n * to a polygon and delegating to the segment-polygon collision function.\n * @param {b2ChainSegment} segmentA - The chain segment shape\n * @param {b2Transform} xfA - Transform for segmentA\n * @param {b2Capsule} capsuleB - The capsule shape defined by two centers and a radius\n * @param {b2Transform} xfB - Transform for capsuleB\n * @param {b2SimplexCache} cache - Simplex cache for persistent contact information\n * @param {b2Manifold} manifold - Contact manifold to store collision results\n * @returns {void}\n */\nexport function b2CollideChainSegmentAndCapsule(segmentA, xfA, capsuleB, xfB, cache, manifold)\n{\n const polyB = b2MakeCapsule(capsuleB.center1, capsuleB.center2, capsuleB.radius);\n\n return b2CollideChainSegmentAndPolygon(segmentA, xfA, polyB, xfB, cache, manifold);\n}\n\nfunction b2ClipSegments(a1, a2, b1, b2, normal, ra, rb, id1, id2, manifold)\n{\n const tangent = b2LeftPerp(normal);\n\n // Barycentric coordinates of each point relative to a1 along tangent\n const lower1 = 0.0;\n const upper1 = b2Dot(b2Sub(a2, a1), tangent);\n\n // Incident edge points opposite of tangent due to CCW winding\n const upper2 = b2Dot(b2Sub(b1, a1), tangent);\n const lower2 = b2Dot(b2Sub(b2, a1), tangent);\n\n // Do segments overlap?\n if (upper2 < lower1 || upper1 < lower2)\n {\n return manifold.clear();\n }\n\n let vLower;\n\n if (lower2 < lower1 && upper2 - lower2 > eps)\n {\n vLower = b2Lerp(b2, b1, (lower1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vLower = b2;\n }\n\n let vUpper;\n\n if (upper2 > upper1 && upper2 - lower2 > eps)\n {\n vUpper = b2Lerp(b2, b1, (upper1 - lower2) / (upper2 - lower2));\n }\n else\n {\n vUpper = b1;\n }\n\n // todo vLower can be very close to vUpper, reduce to one point?\n\n const separationLower = b2Dot(b2Sub(vLower, a1), normal);\n const separationUpper = b2Dot(b2Sub(vUpper, a1), normal);\n\n // Put contact points at midpoint, accounting for radii\n vLower = b2MulAdd(vLower, 0.5 * (ra - rb - separationLower), normal);\n vUpper = b2MulAdd(vUpper, 0.5 * (ra - rb - separationUpper), normal);\n\n const radius = ra + rb;\n\n manifold.normalX = normal.x; // PJB - manifold.normal = normal; <<< reference copy!!\n manifold.normalY = normal.y;\n\n const p0 = manifold.points[0];\n p0.anchorAX = vLower.x;\n p0.anchorAY = vLower.y;\n p0.separation = separationLower - radius;\n p0.id = id1;\n\n const p1 = manifold.points[1];\n\n // p1.anchorA = vUpper;\n p1.anchorAX = vUpper.x;\n p1.anchorAY = vUpper.y;\n p1.separation = separationUpper - radius;\n p1.id = id2;\n\n manifold.pointCount = 2;\n\n return manifold;\n}\n\nconst b2NormalType = {\n b2_normalSkip: 0,\n b2_normalAdmit: 1,\n b2_normalSnap: 2\n};\n\nfunction b2ClassifyNormal(params, normal)\n{\n const sinTol = 0.01;\n\n if (b2Dot(normal, params.edge1) <= 0.0)\n {\n // Normal points towards the segment tail\n if (params.convex1)\n {\n if (b2Cross(normal, params.normal0) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n else\n {\n // Normal points towards segment head\n if (params.convex2)\n {\n if (b2Cross(params.normal2, normal) > sinTol)\n {\n return b2NormalType.b2_normalSkip;\n }\n\n return b2NormalType.b2_normalAdmit;\n }\n else\n {\n return b2NormalType.b2_normalSnap;\n }\n }\n}\n\nclass b2ChainSegmentParams\n{\n constructor()\n {\n this.edge1 = new b2Vec2();\n this.normal0 = new b2Vec2();\n this.normal2 = new b2Vec2();\n this.convex1 = false;\n this.convex2 = false;\n \n }\n};\n\n/**\n * @function b2CollideChainSegmentAndPolygon\n * @param {b2ChainSegment} chainSegmentA - The chain segment shape A\n * @param {b2Transform} xfA - Transform for shape A\n * @param {b2Polygon} polygonB - The polygon shape B\n * @param {b2Transform} xfB - Transform for shape B\n * @param {b2DistanceCache} cache - Cache for distance calculations\n * @param {b2Manifold} manifold - The contact manifold to populate\n * @returns {b2Manifold} The populated contact manifold\n * @description\n * Computes the collision manifold between a chain segment (a segment with rounded corners)\n * and a polygon. The function handles edge cases including convex/concave corners and\n * determines contact points and normals. The manifold is populated with contact points\n * and can contain 0, 1 or 2 contact points depending on the collision configuration.\n */\nexport function b2CollideChainSegmentAndPolygon(chainSegmentA, xfA, polygonB, xfB, cache, manifold)\n{\n b2InvMulTransformsOut(xfA, xfB, xf);\n\n const centroidB = b2TransformPoint(xf, polygonB.centroid);\n const radiusB = polygonB.radius;\n\n const p1 = chainSegmentA.segment.point1;\n const p2 = chainSegmentA.segment.point2;\n\n const edge1 = b2Normalize(b2Sub(p2, p1));\n\n const chainParams = new b2ChainSegmentParams();\n chainParams.edge1 = edge1.clone();\n\n const convexTol = 0.01;\n const edge0 = b2Normalize(b2Sub(p1, chainSegmentA.ghost1));\n chainParams.normal0 = b2RightPerp(edge0);\n chainParams.convex1 = b2Cross(edge0, edge1) >= convexTol;\n\n const edge2 = b2Normalize(b2Sub(chainSegmentA.ghost2, p2));\n chainParams.normal2 = b2RightPerp(edge2);\n chainParams.convex2 = b2Cross(edge1, edge2) >= convexTol;\n\n const normal1 = b2RightPerp(edge1);\n const behind1 = b2Dot(normal1, b2Sub(centroidB, p1)) < 0.0;\n let behind0 = true;\n let behind2 = true;\n\n if (chainParams.convex1)\n {\n behind0 = b2Dot(chainParams.normal0, b2Sub(centroidB, p1)) < 0.0;\n }\n\n if (chainParams.convex2)\n {\n behind2 = b2Dot(chainParams.normal2, b2Sub(centroidB, p2)) < 0.0;\n }\n\n if (behind1 && behind0 && behind2)\n {\n return manifold.clear();\n }\n\n const count = polygonB.count;\n const vertices = [];\n const normals = [];\n\n for (let i = 0; i < count; ++i)\n {\n vertices[i] = b2TransformPoint(xf, polygonB.vertices[i]);\n normals[i] = b2RotateVector(xf.q, polygonB.normals[i]);\n }\n\n const input = new b2DistanceInput();\n input.proxyA = b2MakeProxy([ chainSegmentA.segment.point1, chainSegmentA.segment.point2 ], 2, 0.0);\n input.proxyB = b2MakeProxy(vertices, count, 0.0);\n input.transformA = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = false;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > radiusB + b2_speculativeDistance)\n {\n return manifold.clear();\n }\n\n const n0 = chainParams.convex1 ? chainParams.normal0 : normal1;\n const n2 = chainParams.convex2 ? chainParams.normal2 : normal1;\n\n let incidentIndex = -1;\n let incidentNormal = -1;\n\n if (behind1 == false && output.distance > 0.1 * b2_linearSlop)\n {\n if (cache.count == 1)\n {\n const pA = output.pointA;\n const pB = output.pointB;\n\n const normal = b2Normalize(b2Sub(pB, pA));\n\n const type = b2ClassifyNormal(chainParams, normal);\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n // manifold.normal = b2RotateVector(xfA.q, normal);\n manifold.normalX = xfA.q.c * normal.x - xfA.q.s * normal.y;\n manifold.normalY = xfA.q.s * normal.x + xfA.q.c * normal.y;\n\n // PJB - renamed cp to mp (it's a manifold point, not a contact/constraint point... confirmed from the C)\n const mp = new b2ManifoldPoint();\n\n // mp.anchorA = b2RotateVector(xfA.q, contactPointA);\n mp.anchorAX = xfA.q.c * pA.x - xfA.q.s * pA.y;\n mp.anchorAY = xfA.q.s * pA.x + xfA.q.c * pA.y;\n\n // mp.anchorB = b2Add(mp.anchorA, b2Sub(xfA.p, xfB.p));\n mp.anchorBX = mp.anchorAX + (xfA.p.x - xfB.p.x);\n mp.anchorBY = mp.anchorAY + (xfA.p.y - xfB.p.y);\n\n // mp.point = b2Add(xfA.p, mp.anchorA);\n mp.pointX = xfA.p.x + mp.anchorAX;\n mp.pointY = xfA.p.y + mp.anchorAY;\n mp.separation = output.distance - radiusB;\n mp.id = B2_MAKE_ID(cache.indexA[0], cache.indexB[0]);\n manifold.points[0] = mp;\n manifold.pointCount = 1;\n\n return manifold;\n }\n\n incidentIndex = cache.indexB[0];\n }\n else\n {\n console.assert(cache.count == 2);\n\n const ia1 = cache.indexA[0];\n const ia2 = cache.indexA[1];\n let ib1 = cache.indexB[0];\n let ib2 = cache.indexB[1];\n\n if (ia1 == ia2)\n {\n console.assert(ib1 != ib2);\n\n let normalB = b2Sub(output.pointA, output.pointB);\n let dot1 = b2Dot(normalB, normals[ib1]);\n let dot2 = b2Dot(normalB, normals[ib2]);\n const ib = dot1 > dot2 ? ib1 : ib2;\n\n normalB = normals[ib];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(normalB));\n\n if (type == b2NormalType.b2_normalSkip)\n {\n return manifold.clear();\n }\n\n if (type == b2NormalType.b2_normalAdmit)\n {\n ib1 = ib;\n ib2 = ib < count - 1 ? ib + 1 : 0;\n\n const b1 = vertices[ib1];\n const b2 = vertices[ib2];\n\n dot1 = b2Dot(normalB, b2Sub(p1, b1));\n dot2 = b2Dot(normalB, b2Sub(p2, b1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, normalB) < b2Dot(normal1, normalB))\n {\n return manifold.clear();\n }\n }\n\n b2ClipSegments(b1, b2, p1, p2, normalB, radiusB, 0.0, B2_MAKE_ID(ib1, 1), B2_MAKE_ID(ib2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normalB));\n manifold.normalX = xfA.q.c * -normalB.x - xfA.q.s * -normalB.y;\n manifold.normalY = xfA.q.s * -normalB.x + xfA.q.c * -normalB.y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n incidentNormal = ib;\n }\n else\n {\n const dot1 = b2Dot(normal1, b2Sub(vertices[ib1], p1));\n const dot2 = b2Dot(normal1, b2Sub(vertices[ib2], p2));\n incidentIndex = dot1 < dot2 ? ib1 : ib2;\n }\n }\n }\n else\n {\n // SAT edge normal\n let edgeSeparation = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(normal1, b2Sub(vertices[i], p1));\n\n if (s < edgeSeparation)\n {\n edgeSeparation = s;\n incidentIndex = i;\n }\n }\n\n // Check convex neighbor for edge separation\n if (chainParams.convex1)\n {\n let s0 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal0, b2Sub(vertices[i], p1));\n\n if (s < s0)\n {\n s0 = s;\n }\n }\n\n if (s0 > edgeSeparation)\n {\n edgeSeparation = s0;\n incidentIndex = -1;\n }\n }\n\n if (chainParams.convex2)\n {\n let s2 = Number.MAX_VALUE;\n\n for (let i = 0; i < count; ++i)\n {\n const s = b2Dot(chainParams.normal2, b2Sub(vertices[i], p2));\n\n if (s < s2)\n {\n s2 = s;\n }\n }\n\n if (s2 > edgeSeparation)\n {\n edgeSeparation = s2;\n incidentIndex = -1;\n }\n }\n\n // SAT polygon normals\n let polygonSeparation = -Number.MAX_VALUE;\n let referenceIndex = -1;\n\n for (let i = 0; i < count; ++i)\n {\n const n = normals[i];\n\n const type = b2ClassifyNormal(chainParams, b2Neg(n));\n\n if (type != b2NormalType.b2_normalAdmit)\n {\n continue;\n }\n\n const p = vertices[i];\n const s = Math.min(b2Dot(n, b2Sub(p2, p)), b2Dot(n, b2Sub(p1, p)));\n\n if (s > polygonSeparation)\n {\n polygonSeparation = s;\n referenceIndex = i;\n }\n }\n\n if (polygonSeparation > edgeSeparation)\n {\n const ia1 = referenceIndex;\n const ia2 = ia1 < count - 1 ? ia1 + 1 : 0;\n const a1 = vertices[ia1];\n const a2 = vertices[ia2];\n\n const n = normals[ia1];\n\n const dot1 = b2Dot(n, b2Sub(p1, a1));\n const dot2 = b2Dot(n, b2Sub(p2, a1));\n\n if (dot1 < dot2)\n {\n if (b2Dot(n0, n) < b2Dot(normal1, n))\n {\n return manifold.clear();\n }\n }\n else\n {\n if (b2Dot(n2, n) < b2Dot(normal1, n))\n {\n return manifold.clear(0);\n }\n }\n\n b2ClipSegments(a1, a2, p1, p2, normals[ia1], radiusB, 0.0, B2_MAKE_ID(ia1, 1), B2_MAKE_ID(ia2, 0), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, b2Neg(normals[ia1]));\n manifold.normalX = xfA.q.c * -normals[ia1].x - xfA.q.s * -normals[ia1].y;\n manifold.normalY = xfA.q.s * -normals[ia1].x + xfA.q.c * -normals[ia1].y;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n }\n\n if (incidentIndex == -1)\n {\n return manifold.clear();\n }\n }\n\n console.assert(incidentNormal != -1 || incidentIndex != -1);\n\n let b1, b2;\n let ib1, ib2;\n\n if (incidentNormal != -1)\n {\n ib1 = incidentNormal;\n ib2 = ib1 < count - 1 ? ib1 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n const i2 = incidentIndex;\n const i1 = i2 > 0 ? i2 - 1 : count - 1;\n const d1 = b2Dot(normal1, normals[i1]);\n const d2 = b2Dot(normal1, normals[i2]);\n\n if (d1 < d2)\n {\n ib1 = i1;\n ib2 = i2;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n else\n {\n ib1 = i2;\n ib2 = i2 < count - 1 ? i2 + 1 : 0;\n b1 = vertices[ib1];\n b2 = vertices[ib2];\n }\n }\n\n b2ClipSegments(p1, p2, b1, b2, normal1, 0.0, radiusB, B2_MAKE_ID(0, ib2), B2_MAKE_ID(1, ib1), manifold);\n\n // manifold.normal = b2RotateVector(xfA.q, manifold.normal);\n manifold.normalX = xfA.q.c * manifold.normalX - xfA.q.s * manifold.normalY;\n manifold.normalY = xfA.q.s * manifold.normalX + xfA.q.c * manifold.normalY;\n\n // manifold.points[0].anchorA = b2RotateVector(xfA.q, manifold.points[0].anchorA);\n manifold.points[0].anchorAX = xfA.q.c * manifold.points[0].anchorAX - xfA.q.s * manifold.points[0].anchorAY;\n manifold.points[0].anchorAY = xfA.q.s * manifold.points[0].anchorAX + xfA.q.c * manifold.points[0].anchorAY;\n\n // manifold.points[1].anchorA = b2RotateVector(xfA.q, manifold.points[1].anchorA);\n manifold.points[1].anchorAX = xfA.q.c * manifold.points[1].anchorAX - xfA.q.s * manifold.points[1].anchorAY;\n manifold.points[1].anchorAY = xfA.q.s * manifold.points[1].anchorAX + xfA.q.c * manifold.points[1].anchorAY;\n const pAB = b2Sub(xfA.p, xfB.p);\n\n // manifold.points[0].anchorB = b2Add(manifold.points[0].anchorA, pAB);\n manifold.points[0].anchorBX = manifold.points[0].anchorAX + pAB.x;\n manifold.points[0].anchorBY = manifold.points[0].anchorAY + pAB.y;\n\n // manifold.points[1].anchorB = b2Add(manifold.points[1].anchorA, pAB);\n manifold.points[1].anchorBX = manifold.points[1].anchorAX + pAB.x;\n manifold.points[1].anchorBY = manifold.points[1].anchorAY + pAB.y;\n\n // manifold.points[0].point = b2Add(xfA.p, manifold.points[0].anchorA);\n manifold.points[0].pointX = xfA.p.x + manifold.points[0].anchorAX;\n manifold.points[0].pointY = xfA.p.y + manifold.points[0].anchorAY;\n\n // manifold.points[1].point = b2Add(xfA.p, manifold.points[1].anchorA);\n manifold.points[1].pointX = xfA.p.x + manifold.points[1].anchorAX;\n manifold.points[1].pointY = xfA.p.y + manifold.points[1].anchorAY;\n\n return manifold;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_NULL_INDEX, b2_graphColorCount } from './include/core_h.js';\nimport { B2_SHAPE_PAIR_KEY, b2AddKey, b2RemoveKey } from './include/table_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AllocId, b2FreeId } from './include/id_pool_h.js';\nimport {\n b2CollideCapsuleAndCircle,\n b2CollideCapsules,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndPolygon,\n b2CollideCircles,\n b2CollidePolygonAndCapsule,\n b2CollidePolygonAndCircle,\n b2CollidePolygons,\n b2CollideSegmentAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon\n} from './include/manifold_h.js';\nimport { b2ContactEndTouchEvent, b2SensorEndTouchEvent, b2ShapeType } from './include/types_h.js';\nimport { b2DistanceCache, b2DistanceInput, b2Manifold } from './include/collision_h.js';\nimport { b2GetBody, b2WakeBody } from './include/body_h.js';\n\nimport { b2ContactSimFlags } from './include/contact_h.js';\nimport { b2MakeShapeDistanceProxy } from './include/shape_h.js';\nimport { b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2SetType } from './include/world_h.js';\nimport { b2ShapeDistance } from './include/distance_h.js';\nimport { b2ShapeId } from './include/id_h.js';\nimport { b2UnlinkContact } from './include/island_h.js';\nimport { eps } from './include/math_functions_h.js';\n\n/**\n * @namespace Contact\n */\n\nexport const b2ContactFlags = {\n b2_contactTouchingFlag: 0x00000001,\n b2_contactHitEventFlag: 0x00000002,\n b2_contactSensorFlag: 0x0000004,\n b2_contactSensorTouchingFlag: 0x00000008,\n b2_contactEnableSensorEvents: 0x00000010,\n b2_contactEnableContactEvents: 0x00000020,\n};\n\nexport class b2ContactEdge\n{\n constructor()\n {\n this.bodyId = 0;\n this.prevKey = 0;\n this.nextKey = 0;\n }\n}\n\nexport class b2Contact\n{\n constructor()\n {\n this.setIndex = 0;\n this.colorIndex = 0;\n this.localIndex = 0;\n this.edges = [ new b2ContactEdge(), new b2ContactEdge() ];\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.islandPrev = 0;\n this.islandNext = 0;\n this.islandId = B2_NULL_INDEX;\n this.contactId = B2_NULL_INDEX;\n this.flags = 0;\n this.isMarked = false;\n }\n}\n\nexport class b2ContactSim\n{\n constructor(manifold = new b2Manifold())\n {\n // GlobalDebug.b2ContactSimCount++;\n this.contactId = 0;\n this._bodyIdA = B2_NULL_INDEX; // debug only\n this._bodyIdB = B2_NULL_INDEX; // debug only\n this.bodySimIndexA = 0;\n this.bodySimIndexB = 0;\n this.shapeIdA = 0;\n this.shapeIdB = 0;\n this.invMassA = 0;\n this.invIA = 0;\n this.invMassB = 0;\n this.invIB = 0;\n this.manifold = manifold;\n this.friction = 0;\n this.restitution = 0;\n this.tangentSpeed = 0;\n this.simFlags = 0;\n this.cache = new b2DistanceCache();\n }\n\n set(src)\n {\n this.contactId = src.contactId;\n this._bodyIdA = src._bodyIdA;\n this._bodyIdB = src._bodyIdB;\n this.bodySimIndexA = src.bodySimIndexA;\n this.bodySimIndexB = src.bodySimIndexB;\n this.shapeIdA = src.shapeIdA;\n this.shapeIdB = src.shapeIdB;\n this.invMassA = src.invMassA;\n this.invIA = src.invIA;\n this.invMassB = src.invMassB;\n this.invIB = src.invIB;\n src.manifold.copyTo(this.manifold);\n this.friction = src.friction;\n this.restitution = src.restitution;\n this.tangentSpeed = src.tangentSpeed;\n this.simFlags = src.simFlags;\n this.cache = src.cache.clone();\n }\n}\n\n// Friction mixing law. The idea is to allow either shape to drive the friction to zero.\n// For example, anything slides on ice.\nfunction b2MixFriction(friction1, friction2)\n{\n return Math.sqrt(friction1 * friction2);\n}\n\n// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.\n// For example, a superball bounces on anything.\nfunction b2MixRestitution(restitution1, restitution2)\n{\n return Math.max(restitution1, restitution2);\n}\n\n// todo make relative for all\n// typedef b2Manifold b2ManifoldFcn(const b2Shape* shapeA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache);\n// function b2ManifoldFcn(shapeA, xfA, shapeB, xfB, cache) {\n// }\n// this is a callback declaration, not required in JS\n\nclass b2ContactRegister\n{\n constructor(fcn = null, primary = false)\n {\n this.fcn = fcn;\n this.primary = primary;\n }\n}\n\nconst s_registers = Array(b2ShapeType.b2_shapeTypeCount).fill().map(() =>\n Array(b2ShapeType.b2_shapeTypeCount).fill().map(() => new b2ContactRegister())\n);\n\nlet s_initialized = false;\n\nexport function b2CircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCircles(shapeA.circle, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsuleAndCircle(shapeA.capsule, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2CapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideCapsules(shapeA.capsule, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCircle(shapeA.polygon, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2PolygonAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygonAndCapsule(shapeA.polygon, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2PolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollidePolygons(shapeA.polygon, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2SegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCircle(shapeA.segment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2SegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndCapsule(shapeA.segment, xfA, shapeB.capsule, xfB, manifold);\n}\n\nexport function b2SegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideSegmentAndPolygon(shapeA.segment, xfA, shapeB.polygon, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCircleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCircle(shapeA.chainSegment, xfA, shapeB.circle, xfB, manifold);\n}\n\nexport function b2ChainSegmentAndCapsuleManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndCapsule(shapeA.chainSegment, xfA, shapeB.capsule, xfB, cache, manifold);\n}\n\nexport function b2ChainSegmentAndPolygonManifold(shapeA, xfA, shapeB, xfB, cache, manifold)\n{\n return b2CollideChainSegmentAndPolygon(shapeA.chainSegment, xfA, shapeB.polygon, xfB, cache, manifold);\n}\n\nexport function b2AddType(fcn, type1, type2)\n{\n console.assert(0 <= type1 && type1 < b2ShapeType.b2_shapeTypeCount);\n console.assert(0 <= type2 && type2 < b2ShapeType.b2_shapeTypeCount);\n s_registers[type1][type2].fcn = fcn;\n s_registers[type1][type2].primary = true;\n\n if ( type1 != type2 )\n {\n s_registers[type2][type1].fcn = fcn;\n s_registers[type2][type1].primary = false;\n }\n}\n\n// add callbacks for each manifold type\nexport function b2InitializeContactRegisters()\n{\n if (s_initialized === false)\n {\n b2AddType(b2CircleManifold, b2ShapeType.b2_circleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleAndCircleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_circleShape);\n b2AddType(b2CapsuleManifold, b2ShapeType.b2_capsuleShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonAndCircleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_circleShape);\n b2AddType(b2PolygonAndCapsuleManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2PolygonManifold, b2ShapeType.b2_polygonShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2SegmentAndCircleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2SegmentAndCapsuleManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2SegmentAndPolygonManifold, b2ShapeType.b2_segmentShape, b2ShapeType.b2_polygonShape);\n b2AddType(b2ChainSegmentAndCircleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_circleShape);\n b2AddType(b2ChainSegmentAndCapsuleManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_capsuleShape);\n b2AddType(b2ChainSegmentAndPolygonManifold, b2ShapeType.b2_chainSegmentShape, b2ShapeType.b2_polygonShape);\n s_initialized = true;\n }\n}\n\nexport function b2CreateContact(world, shapeA, shapeB)\n{\n const type1 = shapeA.type;\n const type2 = shapeB.type;\n\n if (s_registers[type1][type2].fcn === null)\n {\n // For example, no segment vs segment collision\n return;\n }\n\n if (s_registers[type1][type2].primary === false)\n {\n // flip order\n b2CreateContact(world, shapeB, shapeA);\n\n return;\n }\n\n const bodyA = b2GetBody(world, shapeA.bodyId);\n const bodyB = b2GetBody(world, shapeB.bodyId);\n\n let setIndex;\n\n if (bodyA.setIndex === b2SetType.b2_awakeSet || bodyB.setIndex === b2SetType.b2_awakeSet)\n {\n setIndex = b2SetType.b2_awakeSet;\n }\n else\n {\n // sleeping and non-touching contacts live in the disabled set\n // later if this set is found to be touching then the sleeping\n // islands will be linked and the contact moved to the merged island\n setIndex = b2SetType.b2_disabledSet;\n }\n\n const set = world.solverSetArray[setIndex];\n\n // Create contact key and contact\n const contactId = b2AllocId(world.contactIdPool);\n\n // grow array until contactId will fit in it\n while (world.contactArray.length <= contactId)\n {\n world.contactArray.push(new b2Contact());\n }\n\n const shapeIdA = shapeA.id;\n const shapeIdB = shapeB.id;\n\n const contact = world.contactArray[contactId];\n contact.contactId = contactId;\n contact.setIndex = setIndex;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n contact.islandId = B2_NULL_INDEX;\n contact.islandPrev = B2_NULL_INDEX;\n contact.islandNext = B2_NULL_INDEX;\n contact.shapeIdA = shapeIdA;\n contact.shapeIdB = shapeIdB;\n contact.isMarked = false;\n contact.flags = 0;\n\n if (shapeA.isSensor || shapeB.isSensor)\n {\n contact.flags |= b2ContactFlags.b2_contactSensorFlag;\n }\n\n if (shapeA.enableSensorEvents || shapeB.enableSensorEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableSensorEvents;\n }\n\n if (shapeA.enableContactEvents || shapeB.enableContactEvents)\n {\n contact.flags |= b2ContactFlags.b2_contactEnableContactEvents;\n }\n\n // Connect to body A\n {\n contact.edges[0].bodyId = shapeA.bodyId;\n contact.edges[0].prevKey = B2_NULL_INDEX;\n contact.edges[0].nextKey = bodyA.headContactKey;\n\n const keyA = (contactId << 1) | 0;\n const headContactKey = bodyA.headContactKey;\n\n if (headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyA;\n }\n bodyA.headContactKey = keyA;\n bodyA.contactCount += 1;\n }\n\n // Connect to body B\n {\n contact.edges[1].bodyId = shapeB.bodyId;\n contact.edges[1].prevKey = B2_NULL_INDEX;\n contact.edges[1].nextKey = bodyB.headContactKey;\n\n const keyB = (contactId << 1) | 1;\n const headContactKey = bodyB.headContactKey;\n\n if (bodyB.headContactKey !== B2_NULL_INDEX)\n {\n const headContact = world.contactArray[headContactKey >> 1];\n headContact.edges[headContactKey & 1].prevKey = keyB;\n }\n bodyB.headContactKey = keyB;\n bodyB.contactCount += 1;\n }\n\n // Add to pair set for fast lookup\n const pairKey = B2_SHAPE_PAIR_KEY(shapeIdA, shapeIdB);\n b2AddKey(world.broadPhase.pairSet, pairKey);\n\n // Contacts are created as non-touching. Later if they are found to be touching\n // they will link islands and be moved into the constraint graph.\n const contactSim = b2AddContact(set.contacts);\n contactSim.contactId = contactId;\n\n // #if B2_VALIDATE\n contactSim._bodyIdA = shapeA.bodyId; // debug only\n contactSim._bodyIdB = shapeB.bodyId; // debug only\n console.assert(contactSim._bodyIdA !== contactSim._bodyIdB);\n\n // #endif\n\n contactSim.bodySimIndexA = B2_NULL_INDEX;\n contactSim.bodySimIndexB = B2_NULL_INDEX;\n contactSim.invMassA = 0.0;\n contactSim.invIA = 0.0;\n contactSim.invMassB = 0.0;\n contactSim.invIB = 0.0;\n contactSim.shapeIdA = shapeIdA;\n contactSim.shapeIdB = shapeIdB;\n\n // contactSim.cache = new b2DistanceCache();\n // contactSim.manifold = new b2Manifold();\n contactSim.friction = b2MixFriction(shapeA.friction, shapeB.friction);\n contactSim.restitution = b2MixRestitution(shapeA.restitution, shapeB.restitution);\n contactSim.tangentSpeed = 0.0;\n contactSim.simFlags = 0;\n\n if (shapeA.enablePreSolveEvents || shapeB.enablePreSolveEvents)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnablePreSolveEvents;\n }\n}\n\nexport function b2DestroyContact(world, contact, wakeBodies)\n{\n // Remove pair from set\n const pairKey = B2_SHAPE_PAIR_KEY(contact.shapeIdA, contact.shapeIdB);\n b2RemoveKey(world.broadPhase.pairSet, pairKey);\n\n const edgeA = contact.edges[0];\n const edgeB = contact.edges[1];\n\n const bodyIdA = edgeA.bodyId;\n const bodyIdB = edgeB.bodyId;\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n const flags = contact.flags;\n\n if ((flags & (b2ContactFlags.b2_contactTouchingFlag | b2ContactFlags.b2_contactSensorTouchingFlag)) != 0 && (flags & (b2ContactFlags.b2_contactEnableContactEvents | b2ContactFlags.b2_contactEnableSensorEvents)) != 0)\n {\n const worldId = world.worldId;\n const shapeA = world.shapeArray[contact.shapeIdA];\n const shapeB = world.shapeArray[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) == 0 );\n const event = new b2ContactEndTouchEvent(shapeIdA, shapeIdB);\n world.contactEndArray.push(event);\n }\n\n if ((flags & b2ContactFlags.b2_contactSensorTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n console.assert( ( flags & b2ContactFlags.b2_contactSensorFlag ) != 0 );\n console.assert( shapeA.isSensor == true || shapeB.isSensor == true );\n console.assert( shapeA.isSensor != shapeB.isSensor );\n\n const event = new b2SensorEndTouchEvent();\n\n if (shapeA.isSensor)\n {\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n }\n else\n {\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n }\n\n world.sensorEndEventArray.push(event);\n }\n }\n\n // Remove from body A\n if (edgeA.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeA.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeA.prevKey & 1];\n prevEdge.nextKey = edgeA.nextKey;\n }\n\n if (edgeA.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeA.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeA.nextKey & 1];\n nextEdge.prevKey = edgeA.prevKey;\n }\n\n const contactId = contact.contactId;\n\n const edgeKeyA = (contactId << 1) | 0;\n\n if (bodyA.headContactKey === edgeKeyA)\n {\n bodyA.headContactKey = edgeA.nextKey;\n }\n\n bodyA.contactCount -= 1;\n\n // Remove from body B\n if (edgeB.prevKey !== B2_NULL_INDEX)\n {\n const prevContact = world.contactArray[edgeB.prevKey >> 1];\n const prevEdge = prevContact.edges[edgeB.prevKey & 1];\n prevEdge.nextKey = edgeB.nextKey;\n }\n\n if (edgeB.nextKey !== B2_NULL_INDEX)\n {\n const nextContact = world.contactArray[edgeB.nextKey >> 1];\n const nextEdge = nextContact.edges[edgeB.nextKey & 1];\n nextEdge.prevKey = edgeB.prevKey;\n }\n\n const edgeKeyB = (contactId << 1) | 1;\n\n if (bodyB.headContactKey === edgeKeyB)\n {\n bodyB.headContactKey = edgeB.nextKey;\n }\n\n bodyB.contactCount -= 1;\n\n // Remove contact from the array that owns it\n if (contact.islandId !== B2_NULL_INDEX)\n {\n b2UnlinkContact(world, contact);\n }\n\n if (contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact is an active constraint\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, contact.colorIndex, contact.localIndex);\n }\n else\n {\n // contact is non-touching or is sleeping or is a sensor\n console.assert(contact.setIndex != b2SetType.b2_awakeSet ||\n (contact.flags & b2ContactFlags.b2_contactTouchingFlag) == 0 ||\n (contact.flags & b2ContactFlags.b2_contactSensorFlag) != 0);\n const set = world.solverSetArray[contact.setIndex];\n const movedIndex = b2RemoveContact(set.contacts, contact.localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContact = set.contacts.data[contact.localIndex];\n world.contactArray[movedContact.contactId].localIndex = contact.localIndex;\n }\n }\n\n contact.contactId = B2_NULL_INDEX;\n contact.setIndex = B2_NULL_INDEX;\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = B2_NULL_INDEX;\n\n b2FreeId(world.contactIdPool, contactId);\n\n if (wakeBodies)\n {\n b2WakeBody(world, bodyA);\n b2WakeBody(world, bodyB);\n }\n}\n\nexport function b2GetContactSim(world, contact)\n{\n if (contact.setIndex === b2SetType.b2_awakeSet && contact.colorIndex !== B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n const color = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < color.contacts.count);\n\n const sim = color.contacts.data[contact.localIndex];\n\n // console.assert(sim._bodyIdA !== B2_NULL_INDEX); //, (new Error().stack));\n // console.assert(sim._bodyIdB !== B2_NULL_INDEX); //, (new Error().stack));\n return sim;\n }\n\n // contact lives in the solver set contacts list\n const set = world.solverSetArray[contact.setIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex <= set.contacts.count);\n\n return set.contacts.data[contact.localIndex];\n}\n\nexport function b2ShouldShapesCollide(filterA, filterB)\n{\n if (filterA.groupIndex === filterB.groupIndex && filterA.groupIndex !== 0)\n {\n return filterA.groupIndex > 0;\n }\n\n const collide = (filterA.maskBits & filterB.categoryBits) !== 0 && (filterA.categoryBits & filterB.maskBits) !== 0;\n\n return collide;\n}\n\nfunction b2TestShapeOverlap(shapeA, xfA, shapeB, xfB, cache)\n{\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shapeA);\n input.proxyB = b2MakeShapeDistanceProxy(shapeB);\n input.transformA = xfA;\n input.transformB = xfB;\n input.useRadii = true;\n\n const output = b2ShapeDistance(cache, input, null, 0);\n\n return output.distance < 10.0 * eps;\n}\n\nconst oldManifold = new b2Manifold();\n\nexport function b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB)\n{\n let touching;\n\n // Is this contact a sensor?\n if (shapeA.isSensor || shapeB.isSensor)\n {\n // Sensors don't generate manifolds or hit events\n touching = b2TestShapeOverlap(shapeA, transformA, shapeB, transformB, contactSim.cache);\n }\n else\n {\n // Copy the existing manifold for matching just below...\n contactSim.manifold.copyTo(oldManifold);\n\n // Compute new manifold\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n\n // Re-use the existing manifold\n fcn(shapeA, transformA, shapeB, transformB, contactSim.cache, contactSim.manifold);\n\n const pointCount = contactSim.manifold.pointCount;\n touching = pointCount > 0;\n\n if ( touching && world.preSolveFcn && ( contactSim.simFlags & b2ContactSimFlags.b2_simEnablePreSolveEvents ) != 0 )\n {\n const shapeIdA = new b2ShapeId(shapeA.id + 1, world.worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, world.worldId, shapeB.revision);\n\n // this call assumes thread safety\n touching = world.preSolveFcn( shapeIdA, shapeIdB, contactSim.manifold, world.preSolveContext );\n\n if ( touching == false )\n {\n // disable contact\n contactSim.manifold.pointCount = 0;\n }\n }\n\n if (touching && (shapeA.enableHitEvents || shapeB.enableHitEvents))\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simEnableHitEvent;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simEnableHitEvent;\n }\n\n // Match old contact ids to new contact ids and copy the\n // stored impulses to warm start the solver.\n for (let i = 0; i < pointCount; ++i)\n {\n const mp2 = contactSim.manifold.points[i];\n\n // shift anchors to be center of mass relative\n // mp2.anchorA = b2Sub(mp2.anchorA, centerOffsetA);\n mp2.anchorAX -= centerOffsetA.x;\n mp2.anchorAY -= centerOffsetA.y;\n\n // mp2.anchorB = b2Sub(mp2.anchorB, centerOffsetB);\n mp2.anchorBX -= centerOffsetB.x;\n mp2.anchorBY -= centerOffsetB.y;\n\n mp2.normalImpulse = 0.0;\n mp2.tangentImpulse = 0.0;\n mp2.maxNormalImpulse = 0.0;\n mp2.normalVelocity = 0.0;\n mp2.persisted = false;\n\n const id2 = mp2.id;\n\n for (let j = 0, l = oldManifold.pointCount; j < l; ++j)\n {\n const mp1 = oldManifold.points[j];\n\n if (mp1.id === id2)\n {\n mp2.normalImpulse = mp1.normalImpulse;\n mp2.tangentImpulse = mp1.tangentImpulse;\n mp2.persisted = true;\n\n break;\n }\n }\n }\n }\n\n if (touching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simTouchingFlag;\n }\n else\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n }\n\n return touching;\n}\n\nexport function b2ComputeManifold(shapeA, transformA, shapeB, transformB, manifold)\n{\n const fcn = s_registers[shapeA.type][shapeB.type].fcn;\n const cache = new b2DistanceCache();\n\n return fcn( shapeA, transformA, shapeB, transformB, cache, manifold );\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport {\n b2ContactFlags,\n b2ContactSim, b2Contact, b2ContactEdge,\n b2InitializeContactRegisters, b2CreateContact, b2DestroyContact, b2GetContactSim, b2ShouldShapesCollide, b2UpdateContact\n} from '../contact_c.js';\n\nexport const b2ContactSimFlags = {\n b2_simTouchingFlag: 0x00010000,\n b2_simDisjoint: 0x00020000,\n b2_simStartedTouching: 0x00040000,\n b2_simStoppedTouching: 0x00080000,\n b2_simEnableHitEvent: 0x00100000,\n b2_simEnablePreSolveEvents: 0x00200000,\n};\n\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport {\n B2_SHAPE_PAIR_KEY,\n b2AddKey,\n b2ClearSet,\n b2ContainsKey,\n b2CreateSet,\n b2DestroySet,\n b2RemoveKey\n} from \"./include/table_h.js\";\nimport { b2AllocateStackItem, b2FreeStackItem } from \"./include/stack_allocator_h.js\";\nimport { b2CreateContact, b2ShouldShapesCollide } from \"./include/contact_h.js\";\nimport { b2DynamicTree, b2DynamicTree_GetUserData, b2DynamicTree_QueryAll } from \"./include/dynamic_tree_h.js\";\nimport {\n b2DynamicTree_Create,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_Destroy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_Rebuild\n} from \"./include/dynamic_tree_h.js\";\nimport { b2GetBody, b2ShouldBodiesCollide } from \"./include/body_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { b2AABB_Overlaps } from \"./include/aabb_h.js\";\nimport { b2BodyType } from \"./include/types_h.js\";\nimport { b2ShapeId } from \"./include/id_h.js\";\nimport { b2ValidateSolverSets } from \"./world_c.js\";\n\n/**\n * @namespace Broadphase\n */\n\n/**\n * @description The broad-phase is used for computing pairs and performing volume queries and ray casts.\n * This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\n * It is up to the client to consume the new pairs and to track subsequent overlap.\n */\nclass b2BroadPhase\n{\n constructor()\n {\n this.trees = new Array(b2BodyType.b2_bodyTypeCount).fill().map(() => new b2DynamicTree());\n\n // this.proxyCount = 0;\n this.moveSet = null;\n this.moveArray = null;\n this.moveResults = null;\n this.movePairs = null;\n this.movePairCapacity = 0;\n this.movePairIndex = 0;\n this.pairSet = null;\n }\n}\n\n// Store the proxy type in the lower 2 bits of the proxy key. This leaves 30 bits for the id.\nconst B2_PROXY_TYPE = (KEY) => KEY & 3;\nconst B2_PROXY_ID = (KEY) => KEY >> 2;\nconst B2_PROXY_KEY = (ID, TYPE) => (ID << 2) | TYPE;\n\n// This is what triggers new contact pairs to be created\n// Warning: this must be called in deterministic order\n// PJB: possible bug in C code, queryProxy is not uint64_t\n// PJB: note that return from b2AddKey is 'false' when the key is added... it returns the 'already added' status\nfunction b2BufferMove(bp, queryProxy)\n{\n // Adding 1 because 0 is the sentinel\n if (!b2AddKey(bp.moveSet, queryProxy + 1))\n {\n bp.moveArray.push(queryProxy);\n }\n}\n\nfunction b2CreateBroadPhase(bp)\n{\n // bp.proxyCount = 0;\n bp.moveSet = b2CreateSet();\n bp.moveArray = [];\n bp.moveResults = null;\n bp.movePairs = null;\n bp.movePairCapacity = 0;\n bp.movePairIndex = 0;\n bp.pairSet = b2CreateSet();\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n bp.trees[i] = b2DynamicTree_Create();\n }\n}\n\nfunction b2DestroyBroadPhase(bp)\n{\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Destroy(bp.trees[i]);\n }\n\n b2DestroySet(bp.moveSet);\n bp.moveArray = null;\n b2DestroySet(bp.pairSet);\n\n Object.keys(bp).forEach(key => delete bp[key]);\n}\n\nfunction b2UnBufferMove(bp, proxyKey)\n{\n const found = b2RemoveKey(bp.moveSet, proxyKey + 1);\n\n if (found)\n {\n const count = bp.moveArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n if (bp.moveArray[i] === proxyKey)\n {\n // swap and pop to remove that element\n bp.moveArray[i] = bp.moveArray[count - 1];\n bp.moveArray.pop();\n\n break;\n }\n }\n }\n}\n\nfunction b2BroadPhase_CreateProxy(bp, proxyType, aabb, categoryBits, shapeIndex, forcePairCreation)\n{\n console.assert(0 <= proxyType && proxyType < b2BodyType.b2_bodyTypeCount);\n const proxyId = b2DynamicTree_CreateProxy(bp.trees[proxyType], aabb, categoryBits, shapeIndex);\n const proxyKey = B2_PROXY_KEY(proxyId, proxyType);\n\n if (proxyType !== b2BodyType.b2_staticBody || forcePairCreation)\n {\n b2BufferMove(bp, proxyKey);\n }\n\n return proxyKey;\n}\n\nfunction b2BroadPhase_DestroyProxy(bp, proxyKey)\n{\n console.assert(bp.moveArray.length === bp.moveSet.size);\n b2UnBufferMove(bp, proxyKey);\n\n // --bp.proxyCount;\n\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(0 <= proxyType && proxyType <= b2BodyType.b2_bodyTypeCount);\n b2DynamicTree_DestroyProxy(bp.trees[proxyType], proxyId);\n}\n\nfunction b2BroadPhase_MoveProxy(bp, proxyKey, aabb)\n{\n const proxyType = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n b2DynamicTree_MoveProxy(bp.trees[proxyType], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nfunction b2BroadPhase_EnlargeProxy(bp, proxyKey, aabb)\n{\n console.assert(proxyKey !== B2_NULL_INDEX);\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n console.assert(typeIndex !== b2BodyType.b2_staticBody);\n\n b2DynamicTree_EnlargeProxy(bp.trees[typeIndex], proxyId, aabb);\n b2BufferMove(bp, proxyKey);\n}\n\nclass b2MovePair\n{\n constructor()\n {\n this.shapeIndexA = 0;\n this.shapeIndexB = 0;\n this.next = null;\n }\n}\n\nclass b2MoveResult\n{\n constructor()\n {\n this.pairList = null;\n }\n}\n\nclass b2QueryPairContext\n{\n constructor()\n {\n this.world = null;\n this.moveResult = null; // b2MoveResult\n this.queryTreeType = 0;\n this.queryProxyKey = 0;\n this.queryShapeIndex = 0;\n }\n}\n\nexport function b2PairQueryCallback(proxyId, shapeId, context)\n{\n const queryContext = context;\n const bp = queryContext.world.broadPhase;\n\n const proxyKey = B2_PROXY_KEY(proxyId, queryContext.queryTreeType);\n\n if (proxyKey === queryContext.queryProxyKey)\n {\n return true;\n }\n\n if (queryContext.queryTreeType !== b2BodyType.b2_staticBody)\n {\n if (proxyKey < queryContext.queryProxyKey && b2ContainsKey(bp.moveSet, proxyKey + 1))\n {\n return true;\n }\n }\n\n const pairKey = B2_SHAPE_PAIR_KEY(shapeId, queryContext.queryShapeIndex);\n\n if (b2ContainsKey(bp.pairSet, pairKey)) // key in set.items\n {\n return true;\n }\n\n let shapeIdA, shapeIdB;\n\n if (proxyKey < queryContext.queryProxyKey)\n {\n shapeIdA = shapeId;\n shapeIdB = queryContext.queryShapeIndex;\n }\n else\n {\n shapeIdA = queryContext.queryShapeIndex;\n shapeIdB = shapeId;\n }\n\n const world = queryContext.world;\n\n // b2CheckId(world.shapeArray, shapeIdA);\n // b2CheckId(world.shapeArray, shapeIdB);\n\n const shapeA = world.shapeArray[shapeIdA];\n const shapeB = world.shapeArray[shapeIdB];\n\n const bodyIdA = shapeA.bodyId;\n const bodyIdB = shapeB.bodyId;\n\n if (bodyIdA === bodyIdB)\n {\n return true;\n }\n\n if (!b2ShouldShapesCollide(shapeA.filter, shapeB.filter))\n {\n return true;\n }\n\n if (shapeA.isSensor && shapeB.isSensor)\n {\n return true;\n }\n\n const bodyA = b2GetBody(world, bodyIdA);\n const bodyB = b2GetBody(world, bodyIdB);\n\n if (!b2ShouldBodiesCollide(world, bodyA, bodyB))\n {\n return true;\n }\n\n const customFilterFcn = queryContext.world.customFilterFcn;\n\n if (customFilterFcn)\n {\n const idA = new b2ShapeId(shapeIdA + 1, world.worldId, shapeA.revision);\n const idB = new b2ShapeId(shapeIdB + 1, world.worldId, shapeB.revision);\n const shouldCollide = customFilterFcn(idA, idB, queryContext.world.customFilterContext);\n\n if (!shouldCollide)\n {\n return true;\n }\n }\n\n const pairIndex = bp.movePairIndex++;\n\n let pair;\n\n if (pairIndex < bp.movePairCapacity)\n {\n pair = bp.movePairs[pairIndex];\n }\n else\n {\n pair = new b2MovePair();\n }\n\n pair.shapeIndexA = shapeIdA;\n pair.shapeIndexB = shapeIdB;\n pair.next = queryContext.moveResult.pairList;\n queryContext.moveResult.pairList = pair;\n\n return true;\n}\n\nfunction b2UpdateBroadPhasePairs(world)\n{\n const bp = world.broadPhase;\n const moveCount = bp.moveArray.length;\n \n if (moveCount === 0) { return; }\n\n const alloc = world.stackAllocator;\n bp.moveResults = b2AllocateStackItem(alloc, moveCount, \"move results\", () => new b2MoveResult());\n \n b2FindPairsTask(0, moveCount, world);\n\n const shapes = world.shapeArray;\n\n for (const result of bp.moveResults)\n {\n for (let pair = result.pairList; pair; pair = pair.next)\n {\n b2CreateContact(world, shapes[pair.shapeIndexA], shapes[pair.shapeIndexB]);\n }\n }\n\n bp.moveArray.length = 0;\n b2ClearSet(bp.moveSet);\n b2FreeStackItem(alloc, bp.moveResults);\n bp.moveResults = null;\n\n b2ValidateSolverSets(world);\n}\n\nfunction b2FindPairsTask(startIndex, endIndex, world)\n{\n const bp = world.broadPhase;\n const queryContext = new b2QueryPairContext();\n queryContext.world = world;\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const proxyKey = bp.moveArray[i];\n\n if (proxyKey === B2_NULL_INDEX) { continue; }\n\n const proxyType = B2_PROXY_TYPE(proxyKey); // possible values = 0,1,2,3\n const proxyId = B2_PROXY_ID(proxyKey);\n queryContext.queryProxyKey = proxyKey;\n \n const baseTree = bp.trees[proxyType];\n const fatAABB = baseTree.nodes[proxyId].aabb; // b2DynamicTree_GetAABB(baseTree, proxyId);\n queryContext.queryShapeIndex = b2DynamicTree_GetUserData(baseTree, proxyId);\n \n const moveResult = bp.moveResults[i];\n moveResult.pairList = null;\n queryContext.moveResult = moveResult;\n\n if (proxyType === b2BodyType.b2_dynamicBody)\n {\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_kinematicBody);\n b2QueryTreeForPairs(bp, fatAABB, queryContext, b2BodyType.b2_staticBody);\n }\n \n queryContext.queryTreeType = b2BodyType.b2_dynamicBody;\n b2DynamicTree_QueryAll(bp.trees[b2BodyType.b2_dynamicBody], fatAABB, queryContext);\n }\n}\n\nfunction b2QueryTreeForPairs(bp, fatAABB, queryContext, treeType)\n{\n queryContext.queryTreeType = treeType;\n b2DynamicTree_QueryAll(bp.trees[treeType], fatAABB, queryContext);\n}\n\nfunction b2BroadPhase_TestOverlap(bp, proxyKeyA, proxyKeyB)\n{\n const typeIndexA = B2_PROXY_TYPE(proxyKeyA);\n const proxyIdA = B2_PROXY_ID(proxyKeyA);\n const typeIndexB = B2_PROXY_TYPE(proxyKeyB);\n const proxyIdB = B2_PROXY_ID(proxyKeyB);\n\n const aabbA = bp.trees[typeIndexA].nodes[proxyIdA].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexA], proxyIdA);\n const aabbB = bp.trees[typeIndexB].nodes[proxyIdB].aabb; // b2DynamicTree_GetAABB(bp.trees[typeIndexB], proxyIdB);\n\n return b2AABB_Overlaps(aabbA, aabbB);\n}\n\nfunction b2BroadPhase_RebuildTrees(bp)\n{\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_dynamicBody]);\n b2DynamicTree_Rebuild(bp.trees[b2BodyType.b2_kinematicBody]);\n}\n\nfunction b2BroadPhase_GetShapeIndex(bp, proxyKey)\n{\n const typeIndex = B2_PROXY_TYPE(proxyKey);\n const proxyId = B2_PROXY_ID(proxyKey);\n\n return b2DynamicTree_GetUserData(bp.trees[typeIndex], proxyId);\n}\n\nexport {\n b2BroadPhase,\n B2_PROXY_ID,\n B2_PROXY_KEY,\n B2_PROXY_TYPE,\n b2BufferMove,\n b2CreateBroadPhase,\n b2DestroyBroadPhase,\n b2BroadPhase_CreateProxy,\n b2BroadPhase_DestroyProxy,\n b2BroadPhase_MoveProxy,\n b2BroadPhase_EnlargeProxy,\n b2BroadPhase_RebuildTrees,\n b2BroadPhase_GetShapeIndex,\n b2UpdateBroadPhasePairs,\n b2BroadPhase_TestOverlap,\n};\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_DEFAULT_MASK_BITS, b2DistanceInput, b2RayCastInput, b2ShapeCastInput } from './include/collision_h.js';\nimport { B2_NULL_INDEX, b2_graphColorCount, b2_linearSlop } from './include/core_h.js';\nimport { B2_PROXY_TYPE, b2BroadPhase, b2BroadPhase_RebuildTrees, b2CreateBroadPhase, b2DestroyBroadPhase, b2UpdateBroadPhasePairs } from './include/broad_phase_h.js';\nimport {\n GlobalDebug,\n b2AABB,\n b2AABB_IsValid,\n b2ClampFloat,\n b2Cross,\n b2IsValid,\n b2ManifoldPointWhere,\n b2MulAdd,\n b2MulSV,\n b2Normalize,\n b2RightPerp,\n b2Rot,\n b2Rot2Where,\n b2Rot_IsValid,\n b2Sub,\n b2Transform,\n b2TransformPoint,\n b2TransformPointOut,\n b2TransformPointOutXf,\n b2Vec2,\n b2Vec2Where,\n b2Vec2_IsValid\n} from './include/math_functions_h.js';\nimport { b2AddContact, b2RemoveContact } from './include/block_array_h.js';\nimport { b2AddContactToGraph, b2RemoveContactFromGraph } from './include/constraint_graph_h.js';\nimport { b2AllocId, b2CreateIdPool, b2DestroyIdPool, b2GetIdCapacity, b2GetIdCount } from './include/id_pool_h.js';\nimport { b2BitSet, b2CreateBitSet, b2DestroyBitSet, b2InPlaceUnion, b2SetBit, b2SetBitCountAndClear } from './include/bitset_h.js';\nimport {\n b2BodyEvents,\n b2BodyType,\n b2ContactBeginTouchEvent,\n b2ContactEndTouchEvent,\n b2ContactEvents,\n b2RayResult,\n b2SensorBeginTouchEvent,\n b2SensorEndTouchEvent,\n b2SensorEvents,\n b2ShapeType,\n b2Validation\n} from './include/types_h.js';\nimport { b2BodyId, b2ShapeId, b2WorldId } from './include/id_h.js';\nimport { b2ComputeCapsuleAABB, b2ComputeCircleAABB, b2ComputePolygonAABB } from './include/geometry_h.js';\nimport { b2ConstraintGraph, b2CreateGraph, b2DestroyGraph, b2_overflowIndex } from './include/constraint_graph_h.js';\nimport { b2Contact, b2ContactFlags, b2ContactSimFlags, b2DestroyContact, b2GetContactSim, b2InitializeContactRegisters, b2UpdateContact } from './include/contact_h.js';\nimport { b2CreateStackAllocator, b2DestroyStackAllocator, b2GetStackAllocation, b2StackAllocator } from './include/stack_allocator_h.js';\nimport { b2DestroySolverSet, b2SolverSet, b2WakeSolverSet } from './include/solver_set_h.js';\nimport { b2DrawJoint, b2GetJointSim } from './include/joint_h.js';\nimport { b2DynamicTree_Query, b2DynamicTree_RayCast, b2DynamicTree_ShapeCast } from './include/dynamic_tree_h.js';\nimport { b2GetBody, b2GetBodySim, b2GetBodyTransformQuick, b2WakeBody } from './include/body_h.js';\nimport { b2GetShapeCentroid, b2GetShapePerimeter, b2MakeShapeDistanceProxy, b2RayCastShape, b2ShapeCastShape } from './include/shape_h.js';\nimport { b2LinkContact, b2UnlinkContact } from './include/island_h.js';\nimport { b2MakeProxy, b2ShapeDistance } from './include/distance_h.js';\nimport { b2MakeSoft, b2Solve, b2StepContext } from './include/solver_h.js';\n\nimport { b2AABB_Overlaps } from './include/aabb_h.js';\nimport { b2CTZ64 } from './include/ctz_h.js';\nimport { b2DistanceCache } from './include/collision_h.js';\nimport { b2HexColor } from './include/types_h.js';\n\n/**\n * @namespace World\n */\n\nexport const B2_MAX_WORLDS = 32;\n\nexport const b2SetType =\n{\n b2_staticSet: 0,\n b2_disabledSet: 1,\n b2_awakeSet: 2,\n b2_firstSleepingSet: 3,\n};\n\nexport class b2World\n{\n stackAllocator = new b2StackAllocator();\n broadPhase = new b2BroadPhase();\n constraintGraph = new b2ConstraintGraph();\n\n // bodyIdPool = new b2IdPool();\n bodyArray = [];\n\n // solverSetIdPool = new b2IdPool();\n solverSetArray = [];\n\n // jointIdPool = new b2IdPool();\n jointArray = [];\n\n // contactIdPool = new b2IdPool();\n contactArray = [];\n\n // islandIdPool = new b2IdPool();\n islandArray = [];\n\n // shapeIdPool = new b2IdPool();\n // chainIdPool = new b2IdPool();\n shapeArray = [];\n chainArray = [];\n taskContextArray = [];\n bodyMoveEventArray = [];\n sensorBeginEventArray = [];\n sensorEndEventArray = [];\n contactBeginArray = [];\n contactEndArray = [];\n contactHitArray = [];\n debugBodySet = new b2BitSet();\n debugJointSet = new b2BitSet();\n debugContactSet = new b2BitSet();\n stepIndex = 0;\n splitIslandId = 0;\n gravity = new b2Vec2(0, 0);\n hitEventThreshold = 0;\n restitutionThreshold = 0;\n maxLinearVelocity = 0;\n contactPushoutVelocity = 0;\n contactHertz = 0;\n contactDampingRatio = 0;\n jointHertz = 0;\n jointDampingRatio = 0;\n revision = 0;\n\n // profile = new b2Profile();\n preSolveFcn = null;\n preSolveContext = null;\n customFilterFcn = null;\n customFilterContext = null;\n workerCount = 0;\n userTaskContext = null;\n userTreeTask = null;\n inv_h = 0;\n worldId = new b2WorldId();\n enableSleep = true;\n locked = false;\n enableWarmStarting = false;\n enableContinuous = false;\n inUse = false;\n}\n\nclass WorldOverlapContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.proxy = null;\n this.transform = null;\n this.userContext = null;\n }\n}\n\nclass WorldRayCastContext\n{\n constructor()\n {\n this.world = null;\n this.fcn = null;\n this.filter = null;\n this.fraction = 0.0;\n this.userContext = null;\n }\n}\n\n// Per thread task storage\n// TODO: the JS conversion has reduced this to single threaded, code mostly left intact temporarily while we get things working.\nexport class b2TaskContext\n{\n constructor()\n {\n // These bits align with the b2ConstraintGraph::contactBlocks and signal a change in contact status\n this.contactStateBitSet = new b2BitSet();\n\n // Used to track bodies with shapes that have enlarged AABBs. This avoids having a bit array\n // that is very large when there are many static shapes.\n this.enlargedSimBitSet = new b2BitSet();\n\n // Used to put islands to sleep\n this.awakeIslandBitSet = new b2BitSet();\n\n // Per worker split island candidate\n this.splitSleepTime = 0;\n this.splitIslandId = B2_NULL_INDEX;\n }\n}\n\nexport function b2GetWorldFromId(id)\n{\n console.assert(1 <= id.index1 && id.index1 <= B2_MAX_WORLDS);\n const world = b2_worlds[id.index1 - 1];\n console.assert(id.index1 === world.worldId + 1);\n console.assert(id.revision === world.revision);\n\n return world;\n}\n\nexport function b2GetWorld(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n return world;\n}\n\nexport function b2GetWorldLocked(index)\n{\n console.assert(0 <= index && index < B2_MAX_WORLDS);\n const world = b2_worlds[index];\n console.assert(world.worldId === index);\n\n if (world.locked)\n {\n console.assert(false);\n\n return null;\n }\n\n return world;\n}\n\n/** @global */\nlet b2_worlds = null;\n\n/**\n * @function b2CreateWorldArray\n * @description\n * Initializes a global array of Box2D world instances if it hasn't been created yet.\n * Creates B2_MAX_WORLDS number of world instances and marks them as not in use.\n * If the array already exists, the function returns without doing anything.\n * @returns {void}\n * @see b2World\n */\nexport function b2CreateWorldArray()\n{\n // don't create a new one if it already exists\n if (b2_worlds != null)\n {\n return;\n }\n\n b2_worlds = [];\n\n for (let i = 0; i < B2_MAX_WORLDS; i++)\n {\n b2_worlds[i] = new b2World();\n b2_worlds[i].inUse = false;\n }\n}\n\n/**\n * @function b2CreateWorld\n * @param {b2WorldDef} def - World definition object containing initialization parameters including:\n * gravity, hitEventThreshold, restitutionThreshold, maximumLinearVelocity,\n * contactPushoutVelocity, contactHertz, contactDampingRatio, jointHertz,\n * jointDampingRatio, enableSleep, enableContinuous\n * @returns {b2WorldId} A world identifier object containing:\n * - index: number (worldId + 1)\n * - revision: number (world revision number)\n * @description\n * Creates and initializes a new Box2D physics world with the specified parameters.\n * The function allocates memory for physics entities (bodies, joints, contacts),\n * initializes contact registers, creates necessary pools and arrays, and sets up\n * the world properties according to the provided definition.\n * @throws {Error} Returns a null world ID (0,0) if no world slots are available\n */\nexport function b2CreateWorld(def /* b2WorldDef */)\n{\n // _Static_assert is not applicable in JS, so we'll skip it\n\n let worldId = B2_NULL_INDEX;\n\n for (let i = 0; i < b2_worlds.length; ++i)\n {\n if (b2_worlds[i].inUse === false)\n {\n worldId = i;\n\n break;\n }\n }\n\n if (worldId === B2_NULL_INDEX)\n {\n return new b2WorldId(0, 0);\n }\n\n b2InitializeContactRegisters();\n\n const world = b2_worlds[worldId];\n const revision = world.revision;\n\n world.worldId = worldId;\n world.revision = revision;\n world.inUse = true;\n\n world.stackAllocator = b2CreateStackAllocator();\n b2CreateBroadPhase(world.broadPhase);\n world.constraintGraph = b2CreateGraph(world.constraintGraph, 16);\n\n // pools\n world.bodyIdPool = b2CreateIdPool(\"body\");\n world.bodyArray = [];\n world.solverSetArray = [];\n\n // add empty static, active, and disabled body sets\n world.solverSetIdPool = b2CreateIdPool(\"solverSet\");\n let set;\n\n // static set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_staticSet].setIndex === b2SetType.b2_staticSet);\n\n // disabled set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_disabledSet].setIndex === b2SetType.b2_disabledSet);\n\n // awake set\n set = new b2SolverSet();\n set.setIndex = b2AllocId(world.solverSetIdPool);\n world.solverSetArray.push(set);\n console.assert(world.solverSetArray[b2SetType.b2_awakeSet].setIndex === b2SetType.b2_awakeSet);\n\n world.shapeIdPool = b2CreateIdPool(\"shapeId\");\n world.shapeArray = [];\n\n world.chainIdPool = b2CreateIdPool(\"chainId\");\n world.chainArray = [];\n\n world.contactIdPool = b2CreateIdPool(\"contactId\");\n world.contactArray = [];\n\n // PJB: allocate some space at the start to reduce the spike in b2CreateContact later\n for (let i = 0; i < 4096; i++)\n {\n world.contactArray.push(new b2Contact());\n }\n\n world.jointIdPool = b2CreateIdPool(\"jointId\");\n world.jointArray = [];\n\n world.islandIdPool = b2CreateIdPool(\"islandId\");\n world.islandArray = [];\n\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n world.stepIndex = 0;\n world.splitIslandId = B2_NULL_INDEX;\n world.gravity = def.gravity;\n world.hitEventThreshold = def.hitEventThreshold;\n world.restitutionThreshold = def.restitutionThreshold;\n world.maxLinearVelocity = def.maximumLinearVelocity;\n world.contactPushoutVelocity = def.contactPushoutVelocity;\n world.contactHertz = def.contactHertz;\n world.contactDampingRatio = def.contactDampingRatio;\n world.jointHertz = def.jointHertz;\n world.jointDampingRatio = def.jointDampingRatio;\n world.enableSleep = def.enableSleep;\n world.locked = false;\n world.enableWarmStarting = true;\n world.enableContinuous = def.enableContinuous;\n world.userTreeTask = null;\n\n world.workerCount = 1;\n world.userTaskContext = null;\n\n world.taskContextArray = [];\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n const context = new b2TaskContext();\n context.contactStateBitSet = b2CreateBitSet(1024);\n context.enlargedSimBitSet = b2CreateBitSet(256),\n context.awakeIslandBitSet = b2CreateBitSet(256);\n world.taskContextArray[i] = context;\n }\n\n world.debugBodySet = b2CreateBitSet(256);\n world.debugJointSet = b2CreateBitSet(256);\n world.debugContactSet = b2CreateBitSet(256);\n\n // add one to worldId so that 0 represents a null b2WorldId\n return new b2WorldId(worldId + 1, world.revision);\n}\n\n/**\n * @function b2DestroyWorld\n * @description\n * Destroys a Box2D world instance and all its associated resources, including debug sets,\n * task contexts, event arrays, chains, bodies, shapes, contacts, joints, islands,\n * solver sets, constraint graph, broad phase, ID pools, and stack allocator.\n * Creates a new empty world instance with an incremented revision number.\n * @param {b2WorldId} worldId - The ID of the world to destroy\n * @returns {void}\n * @throws {Error} Throws an assertion error if a null chain has non-null shape indices\n */\nexport function b2DestroyWorld(worldId)\n{\n let world = b2GetWorldFromId(worldId);\n\n b2DestroyBitSet(world.debugBodySet);\n b2DestroyBitSet(world.debugJointSet);\n b2DestroyBitSet(world.debugContactSet);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n b2DestroyBitSet(world.taskContextArray[i].contactStateBitSet);\n b2DestroyBitSet(world.taskContextArray[i].enlargedSimBitSet);\n b2DestroyBitSet(world.taskContextArray[i].awakeIslandBitSet);\n }\n\n world.taskContextArray = null;\n\n world.bodyMoveEventArray = null;\n world.sensorBeginEventArray = null;\n world.sensorEndEventArray = null;\n world.contactBeginArray = null;\n world.contactEndArray = null;\n world.contactHitArray = null;\n\n const chainCapacity = world.chainArray.length;\n\n for (let i = 0; i < chainCapacity; ++i)\n {\n const chain = world.chainArray[i];\n\n if (chain.id !== B2_NULL_INDEX)\n {\n chain.shapeIndices = null;\n }\n else\n {\n console.assert(chain.shapeIndices === null);\n }\n }\n\n world.bodyArray = null;\n world.shapeArray = null;\n world.chainArray = null;\n world.contactArray = null;\n world.jointArray = null;\n world.islandArray = null;\n\n const setCapacity = world.solverSetArray.length;\n\n for (let i = 0; i < setCapacity; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n b2DestroySolverSet(world, i);\n }\n }\n\n // b2DestroyArray(world.solverSetArray);\n world.solverSetArray = null;\n\n b2DestroyGraph(world.constraintGraph);\n b2DestroyBroadPhase(world.broadPhase);\n\n b2DestroyIdPool(world.bodyIdPool);\n b2DestroyIdPool(world.shapeIdPool);\n b2DestroyIdPool(world.chainIdPool);\n b2DestroyIdPool(world.contactIdPool);\n b2DestroyIdPool(world.jointIdPool);\n b2DestroyIdPool(world.islandIdPool);\n b2DestroyIdPool(world.solverSetIdPool);\n\n b2DestroyStackAllocator(world.stackAllocator);\n\n // Wipe world but preserve revision\n const revision = world.revision;\n world = new b2World();\n world.worldId = B2_NULL_INDEX;\n world.revision = revision + 1;\n}\n\nconst centerOffsetA = new b2Vec2();\nconst centerOffsetB = new b2Vec2();\n\nfunction b2CollideTask(startIndex, endIndex, threadIndex, context)\n{\n // b2TracyCZoneNC(collide_task, \"Collide Task\", b2HexColor.b2_colorDodgerBlue, true);\n\n const stepContext = context;\n const world = stepContext.world;\n console.assert(threadIndex < world.workerCount);\n const taskContext = world.taskContextArray[threadIndex];\n const contactSims = stepContext.contacts;\n const shapes = world.shapeArray;\n const bodies = world.bodyArray;\n\n console.assert(startIndex < endIndex);\n\n for (let i = startIndex; i < endIndex; ++i)\n {\n const contactSim = contactSims[i];\n\n const contactId = contactSim.contactId;\n\n const shapeA = shapes[contactSim.shapeIdA];\n const shapeB = shapes[contactSim.shapeIdB];\n\n // Do proxies still overlap? (Without this check, polygon collision increases from 1200 to 6400 both max... not as much as I expected for 1000 object tumbler)\n const overlap = b2AABB_Overlaps(shapeA.fatAABB, shapeB.fatAABB);\n\n if (!overlap)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simDisjoint;\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simTouchingFlag;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else\n {\n const wasTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n // Update contact respecting shape/body order (A,B)\n const bodyA = bodies[shapeA.bodyId];\n const bodyB = bodies[shapeB.bodyId];\n const bodySimA = b2GetBodySim(world, bodyA);\n const bodySimB = b2GetBodySim(world, bodyB);\n\n // avoid cache misses in b2PrepareContactsTask\n contactSim.bodySimIndexA = bodyA.setIndex === b2SetType.b2_awakeSet ? bodyA.localIndex : B2_NULL_INDEX;\n contactSim.invMassA = bodySimA.invMass;\n contactSim.invIA = bodySimA.invInertia;\n\n contactSim.bodySimIndexB = bodyB.setIndex === b2SetType.b2_awakeSet ? bodyB.localIndex : B2_NULL_INDEX;\n contactSim.invMassB = bodySimB.invMass;\n contactSim.invIB = bodySimB.invInertia;\n\n const transformA = bodySimA.transform;\n const transformB = bodySimB.transform;\n\n // let centerOffsetA = b2RotateVector(transformA.q, bodySimA.localCenter);\n centerOffsetA.x = transformA.q.c * bodySimA.localCenter.x - transformA.q.s * bodySimA.localCenter.y;\n centerOffsetA.y = transformA.q.s * bodySimA.localCenter.x + transformA.q.c * bodySimA.localCenter.y;\n\n // let centerOffsetB = b2RotateVector(transformB.q, bodySimB.localCenter);\n centerOffsetB.x = transformB.q.c * bodySimB.localCenter.x - transformB.q.s * bodySimB.localCenter.y;\n centerOffsetB.y = transformB.q.s * bodySimB.localCenter.x + transformB.q.c * bodySimB.localCenter.y;\n\n // This updates solid contacts and sensors\n const touching = b2UpdateContact(world, contactSim, shapeA, transformA, centerOffsetA, shapeB, transformB, centerOffsetB);\n\n // State changes that affect island connectivity. Also contact and sensor events.\n if (touching && !wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStartedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n else if (!touching && wasTouching)\n {\n contactSim.simFlags |= b2ContactSimFlags.b2_simStoppedTouching;\n b2SetBit(taskContext.contactStateBitSet, contactId);\n }\n }\n }\n\n // b2TracyCZoneEnd(collide_task);\n}\n\nexport function b2AddNonTouchingContact(world, contact, contactSim)\n{\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n contact.colorIndex = B2_NULL_INDEX;\n contact.localIndex = set.contacts.count;\n const newContactSim = b2AddContact(set.contacts);\n newContactSim.set(contactSim);\n}\n\nexport function b2RemoveNonTouchingContact(world, setIndex, localIndex)\n{\n // (world.solverSetArray, setIndex);\n const set = world.solverSetArray[setIndex];\n const movedIndex = b2RemoveContact(set.contacts, localIndex);\n\n if (movedIndex !== B2_NULL_INDEX)\n {\n const movedContactSim = set.contacts.data[localIndex];\n\n // b2CheckIndex(world.contactArray, movedContactSim.contactId);\n const movedContact = world.contactArray[movedContactSim.contactId];\n console.assert(movedContact.setIndex === setIndex);\n console.assert(movedContact.localIndex === movedIndex);\n console.assert(movedContact.colorIndex === B2_NULL_INDEX);\n movedContact.localIndex = localIndex;\n }\n}\n\n// Narrow-phase collision\nexport function b2Collide(context)\n{\n const world = context.world;\n\n console.assert(world.workerCount > 0);\n\n // b2TracyCZoneNC(collide, \"Collide\", b2HexColor.b2_colorDarkOrchid, true);\n\n // Rebuild the collision tree for dynamic and kinematic bodies to keep their query performance good\n b2BroadPhase_RebuildTrees(world.broadPhase);\n\n // gather contacts into a single array\n let contactCount = 0;\n const graphColors = world.constraintGraph.colors;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n contactCount += graphColors[i].contacts.count;\n }\n\n const nonTouchingCount = world.solverSetArray[b2SetType.b2_awakeSet].contacts.count;\n contactCount += nonTouchingCount;\n\n if (contactCount == 0)\n {\n // b2TracyCZoneEnd(collide);\n return;\n }\n\n const contactSims = [];\n\n let contactIndex = 0;\n\n for (let i = 0; i < b2_graphColorCount; ++i)\n {\n const color = graphColors[i];\n const count = color.contacts.count;\n const base = color.contacts.data;\n\n for (let j = 0; j < count; ++j)\n {\n console.assert(base[j]._bodyIdA !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n console.assert(base[j]._bodyIdB !== B2_NULL_INDEX, `${j} ${i} ${color} ${contactIndex}`);\n contactSims.push(base[j]);\n contactIndex += 1;\n }\n }\n\n {\n const base = world.solverSetArray[b2SetType.b2_awakeSet].contacts.data;\n\n for (let i = 0; i < nonTouchingCount; ++i)\n {\n console.assert(base[i]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(base[i]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactSims.push(base[i]);\n console.assert(contactSims[contactIndex]._bodyIdA !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n console.assert(contactSims[contactIndex]._bodyIdB !== B2_NULL_INDEX, `${i} ${contactIndex}`);\n contactIndex += 1;\n }\n }\n\n console.assert(contactIndex == contactCount);\n\n // b2StepContext (created per b2World_Step)\n context.contacts = contactSims;\n\n // Contact bit set on ids because contact pointers are unstable as they move between touching and not touching.\n const contactIdCapacity = b2GetIdCapacity(world.contactIdPool);\n\n for (let i = 0; i < world.workerCount; ++i)\n {\n world.taskContextArray[i].contactStateBitSet = b2SetBitCountAndClear(world.taskContextArray[i].contactStateBitSet, contactIdCapacity);\n }\n\n // PJB: 19/11/2024 this 'task' type function is definitely needed for collisions\n b2CollideTask(0, contactCount, 0, context);\n\n // b2FreeStackItem(world.stackAllocator, contactSims);\n context.contacts = null;\n\n // Serially update contact state\n\n // Bitwise OR all contact bits\n const bitSet = world.taskContextArray[0].contactStateBitSet;\n\n for (let i = 1; i < world.workerCount; ++i)\n {\n b2InPlaceUnion(bitSet, world.taskContextArray[i].contactStateBitSet);\n }\n\n const contacts = world.contactArray;\n const awakeSet = world.solverSetArray[b2SetType.b2_awakeSet];\n\n const shapes = world.shapeArray;\n const worldId = world.worldId;\n\n // Process contact state changes. Iterate over set bits\n for (let k = 0; k < bitSet.blockCount; ++k)\n {\n let bits = bitSet.bits[k];\n\n while (bits != 0n)\n {\n const ctz = b2CTZ64(bits);\n const contactId = 64 * k + ctz;\n\n const contact = contacts[contactId];\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n const colorIndex = contact.colorIndex;\n const localIndex = contact.localIndex;\n\n let contactSim;\n\n if (colorIndex != B2_NULL_INDEX)\n {\n // contact lives in constraint graph\n console.assert(0 <= colorIndex && colorIndex < b2_graphColorCount);\n const color = graphColors[colorIndex];\n console.assert(0 <= localIndex && localIndex < color.contacts.count);\n contactSim = color.contacts.data[localIndex];\n }\n else\n {\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n }\n\n const shapeA = shapes[contact.shapeIdA];\n const shapeB = shapes[contact.shapeIdB];\n const shapeIdA = new b2ShapeId(shapeA.id + 1, worldId, shapeA.revision);\n const shapeIdB = new b2ShapeId(shapeB.id + 1, worldId, shapeB.revision);\n const flags = contact.flags;\n const simFlags = contactSim.simFlags;\n\n if (simFlags & b2ContactSimFlags.b2_simDisjoint)\n {\n // Was touching?\n if ((flags & b2ContactFlags.b2_contactTouchingFlag) != 0 && (flags & b2ContactFlags.b2_contactEnableContactEvents) != 0)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n // Bounding boxes no longer overlap\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n b2DestroyContact(world, contact, false);\n\n // contact = null;\n // contactSim = null;\n }\n else if (simFlags & b2ContactSimFlags.b2_simStartedTouching)\n {\n console.assert(contact.islandId == B2_NULL_INDEX);\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorBeginEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorBeginTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorBeginEventArray.push(event);\n }\n }\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n contact.flags |= b2ContactFlags.b2_contactSensorTouchingFlag;\n }\n else\n {\n // Contact is solid\n if (flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactBeginTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n event.manifold = contactSim.manifold;\n world.contactBeginArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount > 0);\n console.assert(contact.setIndex == b2SetType.b2_awakeSet);\n\n // Link first because this wakes colliding bodies and ensures the body sims\n // are in the correct place.\n contact.flags |= b2ContactFlags.b2_contactTouchingFlag;\n b2LinkContact(world, contact);\n\n // Make sure these didn't change\n console.assert(contact.colorIndex == B2_NULL_INDEX);\n console.assert(contact.localIndex == localIndex);\n\n // Contact sim pointer may have become orphaned due to awake set growth,\n // so I just need to refresh it.\n console.assert(0 <= localIndex && localIndex < awakeSet.contacts.count);\n contactSim = awakeSet.contacts.data[localIndex];\n\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStartedTouching;\n\n b2AddContactToGraph(world, contactSim, contact);\n b2RemoveNonTouchingContact(world, b2SetType.b2_awakeSet, localIndex);\n\n // contactSim = null;\n }\n }\n else if (simFlags & b2ContactSimFlags.b2_simStoppedTouching)\n {\n contactSim.simFlags &= ~b2ContactSimFlags.b2_simStoppedTouching;\n\n if ((flags & b2ContactFlags.b2_contactSensorFlag) != 0)\n {\n // Contact is a sensor\n contact.flags &= ~b2ContactFlags.b2_contactSensorTouchingFlag;\n\n if ((flags & b2ContactFlags.b2_contactEnableSensorEvents) != 0)\n {\n if (shapeA.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdA;\n event.visitorShapeId = shapeIdB;\n world.sensorEndEventArray.push(event);\n }\n\n if (shapeB.isSensor)\n {\n const event = new b2SensorEndTouchEvent();\n event.sensorShapeId = shapeIdB;\n event.visitorShapeId = shapeIdA;\n world.sensorEndEventArray.push(event);\n }\n }\n }\n else\n {\n // Contact is solid\n contact.flags &= ~b2ContactFlags.b2_contactTouchingFlag;\n\n if (contact.flags & b2ContactFlags.b2_contactEnableContactEvents)\n {\n const event = new b2ContactEndTouchEvent();\n event.shapeIdA = shapeIdA;\n event.shapeIdB = shapeIdB;\n world.contactEndArray.push(event);\n }\n\n console.assert(contactSim.manifold.pointCount == 0);\n\n b2UnlinkContact(world, contact);\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n\n b2AddNonTouchingContact(world, contact, contactSim);\n b2RemoveContactFromGraph(world, bodyIdA, bodyIdB, colorIndex, localIndex);\n\n // contact = null;\n // contactSim = null;\n }\n }\n\n // Clear the smallest set bit\n bits = bits & (bits - 1n);\n }\n }\n\n b2ValidateSolverSets(world);\n b2ValidateContacts(world);\n\n // b2TracyCZoneEnd(contact_state);\n // b2TracyCZoneEnd(collide);\n}\n\nGlobalDebug.b2Vec2Count = 0;\nb2Vec2Where.calls = {};\nGlobalDebug.b2Rot2Count = 0;\nb2Rot2Where.calls = {};\nGlobalDebug.b2ManifoldCount = 0;\nGlobalDebug.b2ManifoldPointCount = 0;\nb2ManifoldPointWhere.calls = {};\nGlobalDebug.b2PolyCollideCount = 0;\nGlobalDebug.b2ContactSimCount = 0;\nGlobalDebug.b2TOIInputCount = 0;\nGlobalDebug.b2ShapeCastPairInputCount = 0;\nGlobalDebug.b2SweepCount = 0;\n\n/**\n * @function b2World_Step\n * @summary Advances the physics simulation by a specified time step.\n * @param {b2WorldId} worldId - The identifier of the physics world to step\n * @param {number} timeStep - The time increment to advance the simulation (in seconds)\n * @param {number} subStepCount - The number of sub-steps to use for the iteration\n * @returns {void}\n * @description\n * Performs one step of physics simulation by updating broad phase pairs,\n * handling collisions, and solving the physics constraints. The function\n * manages contact events, sensor events, and body movement events during\n * the simulation step. It also handles warm starting and enforces velocity\n * limits based on world settings.\n * @throws {Error} Throws an assertion error if the world's stack allocator\n * is not empty after the step completes.\n * @note The function will not execute if the world is locked or if timeStep is 0.\n */\nexport function b2World_Step(worldId, timeStep, subStepCount)\n{\n GlobalDebug.b2FrameCount++;\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n // Prepare to capture events\n // Ensure user does not access stale data if there is an early return\n world.bodyMoveEventArray = [];\n world.sensorBeginEventArray = [];\n world.sensorEndEventArray = [];\n world.contactBeginArray = [];\n world.contactEndArray = [];\n world.contactHitArray = [];\n\n if (timeStep === 0.0)\n {\n // todo would be useful to still process collision while paused\n return;\n }\n\n world.locked = true;\n b2UpdateBroadPhasePairs(world);\n \n const context = new b2StepContext();\n context.world = world;\n context.dt = timeStep;\n context.subStepCount = Math.max(1, subStepCount);\n\n if (timeStep > 0.0)\n {\n context.inv_dt = 1.0 / timeStep;\n context.h = timeStep / context.subStepCount;\n context.inv_h = context.subStepCount * context.inv_dt;\n }\n else\n {\n context.inv_dt = 0.0;\n context.h = 0.0;\n context.inv_h = 0.0;\n }\n\n world.inv_h = context.inv_h;\n\n // Hertz values get reduced for large time steps\n const contactHertz = Math.min(world.contactHertz, 0.25 * context.inv_h);\n const jointHertz = Math.min(world.jointHertz, 0.125 * context.inv_h);\n\n context.contactSoftness = b2MakeSoft(contactHertz, world.contactDampingRatio, context.h);\n context.staticSoftness = b2MakeSoft(2.0 * contactHertz, world.contactDampingRatio, context.h);\n context.jointSoftness = b2MakeSoft(jointHertz, world.jointDampingRatio, context.h);\n\n context.restitutionThreshold = world.restitutionThreshold;\n context.maxLinearVelocity = world.maxLinearVelocity;\n context.enableWarmStarting = world.enableWarmStarting;\n\n // Update contacts\n b2Collide(context);\n\n // Integrate velocities, solve velocity constraints, and integrate positions.\n if (context.dt > 0.0)\n {\n b2Solve(world, context);\n }\n\n world.locked = false;\n\n console.assert(b2GetStackAllocation(world.stackAllocator) == 0, `world.stackAllocator entries not empty ${b2GetStackAllocation(world.stackAllocator)}`);\n}\n\nconst p1 = new b2Vec2();\nconst p2 = new b2Vec2();\nconst q = new b2Rot();\nconst txf = new b2Transform(p1, q);\n\nexport function b2DrawShape(draw, shape, transform, color)\n{\n const xf = transform.clone();\n \n switch (shape.type)\n {\n case b2ShapeType.b2_capsuleShape:\n {\n const capsule = shape.capsule;\n b2TransformPointOut(xf, capsule.center1, p1);\n b2TransformPointOut(xf, capsule.center2, p2);\n\n if (shape.image)\n {\n draw.DrawImageCapsule(p1, p2, capsule.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCapsule(p1, p2, capsule.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_circleShape:\n {\n const circle = shape.circle;\n b2TransformPointOutXf(xf, circle.center, txf);\n\n if (shape.image)\n {\n draw.DrawImageCircle(txf, circle.radius, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidCircle(txf, circle.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_polygonShape:\n {\n const poly = shape.polygon;\n\n if (shape.image)\n {\n draw.DrawImagePolygon(xf, shape, draw.context);\n }\n else if (!shape.imageNoDebug)\n {\n draw.DrawSolidPolygon(xf, poly.vertices, poly.count, poly.radius, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_segmentShape:\n {\n const segment = shape.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n }\n\n break;\n\n case b2ShapeType.b2_chainSegmentShape:\n {\n const segment = shape.chainSegment.segment;\n b2TransformPointOut(xf, segment.point1, p1);\n b2TransformPointOut(xf, segment.point2, p2);\n\n if (!shape.imageNoDebug)\n {\n draw.DrawSegment(p1, p2, color, draw.context);\n }\n\n // draw.DrawPoint(p2, 4.0, color, draw.context);\n // draw.DrawSegment(p1, b2Lerp(p1, p2, 0.1), b2HexColor.b2_colorPaleGreen, draw.context);\n }\n\n break;\n \n default:\n break;\n }\n}\n\n// DrawContext is converted to a class in JavaScript\nclass DrawContext\n{\n constructor(world, draw)\n {\n this.world = world;\n this.draw = draw;\n \n }\n}\n\nfunction DrawQueryCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const drawContext = context;\n const world = drawContext.world;\n const draw = drawContext.draw;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n b2SetBit(world.debugBodySet, shape.bodyId);\n\n if (draw.drawShapes)\n {\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n const bodySim = b2GetBodySim(world, body);\n\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, bodySim.transform, color);\n }\n\n if (draw.drawAABBs)\n {\n const aabb = shape.fatAABB;\n\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(vs, 4, b2HexColor.b2_colorGold, draw.context);\n }\n\n return true;\n}\n\nfunction b2DrawWithBounds(world, draw)\n{\n console.assert(b2AABB_IsValid(draw.drawingBounds));\n\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const graphColors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n const bodyCapacity = b2GetIdCapacity(world.bodyIdPool);\n world.debugBodySet = b2SetBitCountAndClear(world.debugBodySet, bodyCapacity);\n\n const jointCapacity = b2GetIdCapacity(world.jointIdPool);\n world.debugJointSet = b2SetBitCountAndClear(world.debugJointSet, jointCapacity);\n\n const contactCapacity = b2GetIdCapacity(world.contactIdPool);\n world.debugContactSet = b2SetBitCountAndClear(world.debugContactSet, contactCapacity);\n\n const drawContext = new DrawContext(world, draw);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], draw.drawingBounds, B2_DEFAULT_MASK_BITS, DrawQueryCallback,\n drawContext);\n }\n\n const wordCount = world.debugBodySet.blockCount;\n const bits = world.debugBodySet.bits;\n\n for (let k = 0; k < wordCount; ++k)\n {\n let word = bits[k];\n\n while (word !== 0)\n {\n const ctz = b2CTZ64(word);\n const bodyId = 64 * k + ctz;\n\n // b2CheckId(world.bodyArray, bodyId);\n const body = world.bodyArray[bodyId];\n\n if (draw.drawMass && body.type === b2BodyType.b2_dynamicBody)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const bodySim = b2GetBodySim(world, body);\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n\n if (draw.drawJoints)\n {\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n const joint = world.jointArray[jointId];\n\n // avoid double draw\n if (b2GetBit(world.debugJointSet, jointId) === false)\n {\n b2DrawJoint(draw, world, joint);\n b2SetBit(world.debugJointSet, jointId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n\n const linearSlop = b2_linearSlop;\n\n if (draw.drawContacts && body.type === b2BodyType.b2_dynamicBody && body.setIndex === b2SetType.b2_awakeSet)\n {\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n const contact = world.contactArray[contactId];\n contactKey = contact.edges[edgeIndex].nextKey;\n\n if (contact.setIndex !== b2SetType.b2_awakeSet || contact.colorIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n // avoid double draw\n if (b2GetBit(world.debugContactSet, contactId) === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n\n const gc = world.constraintGraph.colors[contact.colorIndex];\n console.assert(0 <= contact.localIndex && contact.localIndex < gc.contacts.count);\n\n const contactSim = gc.contacts.data[contact.localIndex];\n const pointCount = contactSim.manifold.pointCount;\n const normal = new b2Vec2(contactSim.manifold.normalX, contactSim.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contactSim.manifold.points[j];\n\n if (draw.drawGraphColors)\n {\n // graph color\n const pointSize = contact.colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, graphColors[contact.colorIndex], draw.context);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${(1000.0 * point.tangentImpulse).toFixed(1)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n\n b2SetBit(world.debugContactSet, contactId);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n }\n\n // Clear the smallest set bit\n word = word & (word - 1);\n }\n }\n}\n\n/**\n * @function b2World_Draw\n * @description\n * Renders debug visualization of a Box2D world, including shapes, joints, AABBs,\n * mass centers, and contact points based on the debug draw flags.\n * @param {b2WorldId} worldId - ID of the Box2D world to render\n * @param {b2DebugDraw} draw - Debug drawing context with rendering flags and methods\n * @returns {void}\n * @throws {Error} Throws assertion error if world is locked or body transform is null\n * @note\n * Drawing is controlled by flags in the draw parameter:\n * - drawShapes: Renders physics bodies/shapes with color coding\n * - drawJoints: Renders all active joints\n * - drawAABBs: Renders axis-aligned bounding boxes\n * - drawMass: Renders center of mass and mass values\n * - drawContacts: Renders contact points and impulses\n * - useDrawingBounds: Uses bounded drawing region\n */\nexport function b2World_Draw(worldId, draw)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n if (draw.useDrawingBounds)\n {\n b2DrawWithBounds(world, draw);\n\n return;\n }\n\n if (draw.drawShapes)\n {\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n console.assert(bodySim.transform != null, \"transform is null for body \" + bodySim.bodyId + \" \" + setIndex + \" \" + bodyIndex);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n\n // 0 = static, 1 = disabled, 2 = awake, 3 = sleeping\n console.assert(body.setIndex === setIndex, `body.setIndex is wrong: ${body.setIndex} != ${setIndex}`);\n\n const xf = bodySim.transform;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n let color;\n\n if (body.setIndex >= b2SetType.b2_firstSleepingSet)\n {\n color = b2HexColor.b2_colorGray;\n }\n else if (shape.customColor !== 0)\n {\n color = shape.customColor;\n }\n else if (body.type === b2BodyType.b2_dynamicBody && bodySim.mass === 0.0)\n {\n // Bad body\n color = b2HexColor.b2_colorRed;\n }\n else if (body.setIndex === b2SetType.b2_disabledSet)\n {\n color = b2HexColor.b2_colorSlateGray;\n }\n else if (shape.isSensor)\n {\n color = b2HexColor.b2_colorWheat;\n }\n else if (bodySim.isBullet && body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorTurquoise;\n }\n else if (body.isSpeedCapped)\n {\n color = b2HexColor.b2_colorYellow;\n }\n else if (bodySim.isFast)\n {\n color = b2HexColor.b2_colorSalmon;\n }\n else if (body.type === b2BodyType.b2_staticBody)\n {\n color = b2HexColor.b2_colorPaleGreen;\n }\n else if (body.type === b2BodyType.b2_kinematicBody)\n {\n color = b2HexColor.b2_colorRoyalBlue;\n }\n else if (body.setIndex === b2SetType.b2_awakeSet)\n {\n color = b2HexColor.b2_colorPink;\n }\n else\n {\n color = b2HexColor.b2_colorGray;\n }\n\n b2DrawShape(draw, shape, xf, color);\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawJoints)\n {\n const count = world.jointArray.length;\n\n for (let i = 0; i < count; ++i)\n {\n const joint = world.jointArray[i];\n\n if (joint.setIndex === B2_NULL_INDEX)\n {\n continue;\n }\n\n b2DrawJoint(draw, world, joint);\n }\n }\n\n if (draw.drawAABBs)\n {\n const color = b2HexColor.b2_colorGray;\n const setIndex = b2SetType.b2_awakeSet;\n\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n const xf = b2Transform.identity();\n\n // const buffer = `${bodySim.bodyId}`;\n // draw.DrawString(bodySim.center, buffer, draw.context);\n\n // b2CheckIndex(world.bodyArray, bodySim.bodyId);\n const body = world.bodyArray[bodySim.bodyId];\n console.assert(body.setIndex === setIndex);\n\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n const shape = world.shapeArray[shapeId];\n const aabb = shape.fatAABB;\n const vs = [\n new b2Vec2(aabb.lowerBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.lowerBoundY),\n new b2Vec2(aabb.upperBoundX, aabb.upperBoundY),\n new b2Vec2(aabb.lowerBoundX, aabb.upperBoundY)\n ];\n\n draw.DrawPolygon(xf, vs, 4, color, draw.context);\n\n shapeId = shape.nextShapeId;\n }\n }\n }\n }\n\n if (draw.drawMass)\n {\n const offset = new b2Vec2(0.1, 0.1);\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n const bodyCount = set.sims.count;\n\n for (let bodyIndex = 0; bodyIndex < bodyCount; ++bodyIndex)\n {\n const bodySim = set.sims.data[bodyIndex];\n\n const transform = new b2Transform(bodySim.center, bodySim.transform.q);\n draw.DrawTransform(transform, draw.context);\n\n const p = b2TransformPoint(transform, offset);\n\n const buffer = ` ${bodySim.mass.toFixed(2)}`;\n draw.DrawString(p, buffer, draw.context);\n }\n }\n }\n\n if (draw.drawContacts)\n {\n const k_impulseScale = 1.0;\n const k_axisScale = 0.3;\n const linearSlop = b2_linearSlop;\n\n const speculativeColor = b2HexColor.b2_colorGray3;\n const addColor = b2HexColor.b2_colorGreen;\n const persistColor = b2HexColor.b2_colorBlue;\n const normalColor = b2HexColor.b2_colorGray9;\n const impulseColor = b2HexColor.b2_colorMagenta;\n const frictionColor = b2HexColor.b2_colorYellow;\n\n const colors = [ b2HexColor.b2_colorRed, b2HexColor.b2_colorOrange, b2HexColor.b2_colorYellow, b2HexColor.b2_colorGreen,\n b2HexColor.b2_colorCyan, b2HexColor.b2_colorBlue, b2HexColor.b2_colorViolet, b2HexColor.b2_colorPink,\n b2HexColor.b2_colorChocolate, b2HexColor.b2_colorGoldenrod, b2HexColor.b2_colorCoral, b2HexColor.b2_colorBlack ];\n\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const graphColor = world.constraintGraph.colors[colorIndex];\n\n const contactCount = graphColor.contacts.count;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = graphColor.contacts.data[contactIndex];\n const pointCount = contact.manifold.pointCount;\n const normal = new b2Vec2(contact.manifold.normalX, contact.manifold.normalY);\n\n for (let j = 0; j < pointCount; ++j)\n {\n const point = contact.manifold.points[j];\n\n if (draw.drawGraphColors && 0 <= colorIndex && colorIndex <= b2_graphColorCount)\n {\n // graph color\n const pointSize = colorIndex === b2_overflowIndex ? 7.5 : 5.0;\n draw.DrawPoint(point.pointX, point.pointY, pointSize, colors[colorIndex], draw.context);\n\n // draw.DrawString(point.position, `${point.color}`);\n }\n else if (point.separation > linearSlop)\n {\n // Speculative\n draw.DrawPoint(point.pointX, point.pointY, 5.0, speculativeColor, draw.context);\n }\n else if (point.persisted === false)\n {\n // Add\n draw.DrawPoint(point.pointX, point.pointY, 10.0, addColor, draw.context);\n }\n else if (point.persisted === true)\n {\n // Persist\n draw.DrawPoint(point.pointX, point.pointY, 5.0, persistColor, draw.context);\n }\n\n if (draw.drawContactNormals)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_axisScale, normal);\n draw.DrawSegment(p1, p2, normalColor, draw.context);\n }\n else if (draw.drawContactImpulses)\n {\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.normalImpulse, normal);\n draw.DrawSegment(p1, p2, impulseColor, draw.context);\n const buffer = `${(1000.0 * point.normalImpulse).toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n\n if (draw.drawFrictionImpulses)\n {\n const tangent = b2RightPerp(normal);\n const p1 = new b2Vec2(point.pointX, point.pointY);\n const p2 = b2MulAdd(p1, k_impulseScale * point.tangentImpulse, tangent);\n draw.DrawSegment(p1, p2, frictionColor, draw.context);\n const buffer = `${point.normalImpulse.toFixed(2)}`;\n draw.DrawString(p1, buffer, draw.context);\n }\n }\n }\n }\n }\n}\n\n/**\n * @function b2World_GetBodyEvents\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @returns {b2BodyEvents} An object containing an array of body move events and their count\n * @description\n * Retrieves the body movement events from a Box2D world. Returns an empty events object\n * if the world is locked. The function copies the world's body move event array and count\n * into a new b2BodyEvents object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetBodyEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2BodyEvents();\n }\n\n const count = world.bodyMoveEventArray.length;\n const events = new b2BodyEvents();\n events.moveEvents = world.bodyMoveEventArray;\n events.moveCount = count;\n\n return events;\n}\n\n/**\n * @function b2World_GetSensorEvents\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {b2SensorEvents} An object containing arrays of sensor begin and end events\n * @description\n * Retrieves the sensor events from a Box2D world. The function returns both begin and end\n * sensor events that occurred during the simulation step. If the world is locked, it returns\n * an empty events object.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_GetSensorEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2SensorEvents();\n }\n\n const beginCount = world.sensorBeginEventArray.length;\n const endCount = world.sensorEndEventArray.length;\n\n const events = new b2SensorEvents();\n events.beginEvents = world.sensorBeginEventArray;\n events.endEvents = world.sensorEndEventArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n\n return events;\n}\n\n/**\n * @function b2World_GetContactEvents\n * @summary Retrieves the contact events from a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2ContactEvents} An object containing arrays of begin, end, and hit contact events,\n * along with their respective counts.\n * @throws {Error} Throws an assertion error if the world is locked.\n * @description\n * Returns a b2ContactEvents object containing three arrays: contactBeginArray,\n * contactEndArray, and contactHitArray, representing different types of contact\n * events that occurred in the physics simulation. The object also includes\n * count values for each type of event.\n */\nexport function b2World_GetContactEvents(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return new b2ContactEvents();\n }\n\n const beginCount = world.contactBeginArray.length;\n const endCount = world.contactEndArray.length;\n const hitCount = world.contactHitArray.length;\n\n const events = new b2ContactEvents();\n events.beginEvents = world.contactBeginArray;\n events.endEvents = world.contactEndArray;\n events.hitEvents = world.contactHitArray;\n events.beginCount = beginCount;\n events.endCount = endCount;\n events.hitCount = hitCount;\n\n return events;\n}\n\n/**\n * Validates a Box2D world identifier.\n * @function b2World_IsValid\n * @param {b2WorldId} id - The world identifier to validate, containing index1 and revision properties\n * @returns {boolean} True if the world ID is valid and matches the stored world revision, false otherwise\n * @description\n * Checks if a world ID is valid by verifying:\n * 1. The ID is not undefined\n * 2. The index is within valid bounds (1 to B2_MAX_WORLDS)\n * 3. The world exists at the specified index\n * 4. The revision number matches the world's current revision\n */\nexport function b2World_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.index1 < 1 || B2_MAX_WORLDS < id.index1)\n {\n return false;\n }\n\n const world = b2_worlds[id.index1 - 1];\n\n if (world.worldId !== id.index1 - 1)\n {\n // world is not allocated\n return false;\n }\n\n return id.revision === world.revision;\n}\n\n/**\n * @function b2Body_IsValid\n * @summary Validates a body ID to ensure it references a valid body in the physics world.\n * @param {b2BodyId} id - The body ID to validate\n * @returns {boolean} True if the ID is valid and references an existing body, false otherwise\n * @description\n * Performs validation checks on a body ID including:\n * - Verifies the ID is defined and is a b2BodyId instance\n * - Checks the world index is within valid bounds\n * - Confirms the world exists and matches the ID\n * - Validates the body index exists in the world\n * - Ensures the body is active and the revision number matches\n */\nexport function b2Body_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (!(id instanceof b2BodyId))\n {\n console.error(`Invalid ID:\\n${new Error().stack}`);\n\n return false;\n }\n\n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n // invalid world\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n if (id.index1 < 1 || world.bodyArray.length < id.index1)\n {\n // invalid index\n return false;\n }\n\n const body = world.bodyArray[id.index1 - 1];\n\n if (body.setIndex === B2_NULL_INDEX)\n {\n // this was freed\n return false;\n }\n\n console.assert(body.localIndex != B2_NULL_INDEX);\n\n if (body.revision !== id.revision)\n {\n // this id is orphaned\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates a shape ID to ensure it references a valid shape in a valid world.\n * @function b2Shape_IsValid\n * @param {b2ShapeId} id - The shape ID to validate, containing world0, index1, and revision properties\n * @returns {boolean} True if the shape ID is valid and references an existing shape, false otherwise\n * @description\n * Checks if a shape ID is valid by verifying:\n * - The ID exists and is not undefined\n * - The world index is within bounds\n * - The referenced world exists and matches the world ID\n * - The shape index is within bounds of the world's shape array\n * - The shape exists and is not marked as null\n * - The shape revision matches the ID's revision\n */\nexport function b2Shape_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const shapeId = id.index1 - 1;\n\n if (shapeId < 0 || world.shapeArray.length <= shapeId)\n {\n return false;\n }\n\n const shape = world.shapeArray[shapeId];\n\n if (shape.id === B2_NULL_INDEX)\n {\n // shape is free\n return false;\n }\n\n console.assert(shape.id == shapeId);\n\n return id.revision === shape.revision;\n}\n\n/**\n * Validates a b2ChainId to ensure it references a valid chain in the Box2D world system.\n * @function b2Chain_IsValid\n * @param {b2ChainId} id - The chain identifier containing world0 (world index),\n * index1 (chain index), and revision properties\n * @returns {boolean} Returns true if the chain ID is valid and matches the current revision,\n * false otherwise\n * @description\n * Checks if a chain ID is valid by verifying:\n * - The ID exists\n * - The world index is within valid bounds\n * - The world exists and matches the ID\n * - The chain index is within valid bounds\n * - The chain exists and is not null\n * - The revision number matches\n */\nexport function b2Chain_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const chainId = id.index1 - 1;\n\n if (chainId < 0 || world.chainArray.length <= chainId)\n {\n return false;\n }\n\n const chain = world.chainArray[chainId];\n\n if (chain.id === B2_NULL_INDEX)\n {\n // chain is free\n return false;\n }\n\n console.assert(chain.id == chainId);\n\n return id.revision === chain.revision;\n}\n\n/**\n * Validates a joint ID to ensure it references a valid joint in the Box2D world.\n * @function b2Joint_IsValid\n * @param {b2JointId} id - The joint ID to validate, containing world0 (world index),\n * index1 (joint index), and revision properties\n * @returns {boolean} True if the joint ID is valid and references an existing joint,\n * false otherwise\n * @description\n * Checks if a joint ID is valid by verifying:\n * - The world index is within bounds\n * - The referenced world exists and matches the ID\n * - The joint index is within bounds\n * - The joint exists and is not null\n * - The revision number matches the joint's revision\n */\nexport function b2Joint_IsValid(id)\n{\n if (id === undefined)\n {\n return false;\n }\n \n if (id.world0 < 0 || B2_MAX_WORLDS <= id.world0)\n {\n return false;\n }\n\n const world = b2_worlds[id.world0];\n\n if (world.worldId !== id.world0)\n {\n // world is free\n return false;\n }\n\n const jointId = id.index1 - 1;\n\n if (jointId < 0 || world.jointArray.length <= jointId)\n {\n return false;\n }\n\n const joint = world.jointArray[jointId];\n\n if (joint.jointId === B2_NULL_INDEX)\n {\n // joint is free\n return false;\n }\n\n console.assert(joint.jointId == jointId);\n\n return id.revision === joint.revision;\n}\n\n/**\n * @function b2World_EnableSleeping\n * @summary Controls the sleep state management of bodies in a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - When true, enables sleep management. When false, wakes all sleeping bodies.\n * @returns {void}\n * @description\n * Enables or disables the sleep management system for the specified Box2D world.\n * When sleep is disabled, all sleeping bodies are awakened. The function has no effect\n * if the world is locked or if the requested sleep state matches the current state.\n * @throws {Error} Throws an assertion error if the world is locked.\n */\nexport function b2World_EnableSleeping(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n if (flag === world.enableSleep)\n {\n return;\n }\n\n world.enableSleep = flag;\n\n if (flag === false)\n {\n const setCount = world.solverSetArray.length;\n\n for (let i = b2SetType.b2_firstSleepingSet; i < setCount; ++i)\n {\n const set = world.solverSetArray[i];\n\n if (set.sims.length > 0)\n {\n b2WakeSolverSet(world, i);\n }\n }\n }\n}\n\n\n\n/**\n * @function b2World_IsSleepingEnabled\n * @summary Is body sleeping enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if sleeping is enabled for the world, false otherwise.\n */\nexport function b2World_IsSleepingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableSleep;\n}\n\n\n/**\n * @function b2World_IsContinuousEnabled\n * @summary Is continuous collision enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if continuous collision is enabled for the world, false otherwise.\n */\nexport function b2World_IsContinuousEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableContinuous;\n}\n\n\n/**\n * @function b2World_GetRestitutionThreshold\n * @summary Get the the restitution speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetRestitutionThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.restitutionThreshold;\n}\n\n\n/**\n * @function b2World_GetHitEventThreshold\n * @summary Get the the hit event speed threshold. Typically in meters per second.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {number} float\n */\nexport function b2World_GetHitEventThreshold(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.hitEventThreshold;\n}\n\n\n/**\n * @function b2World_IsWarmStartingEnabled\n * @summary Is constraint warm starting enabled?\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {boolean} True if constraint warm starting is enabled for the world, false otherwise.\n */\nexport function b2World_IsWarmStartingEnabled(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.enableWarmStarting;\n}\n\n\n/**\n * @function b2World_EnableWarmStarting\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {boolean} flag - Boolean value to enable or disable warm starting\n * @returns {void}\n * @description\n * Enables or disables warm starting for the specified Box2D world. Warm starting\n * cannot be modified while the world is locked. If the world is locked when this\n * function is called, the function will return without making any changes.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_EnableWarmStarting(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableWarmStarting = flag;\n}\n\n/**\n * @function b2World_EnableContinuous\n * @summary Enables or disables continuous collision detection for a Box2D world.\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @param {boolean} flag - True to enable continuous collision detection, false to disable it.\n * @returns {void}\n * @description\n * Sets the continuous collision detection state for the specified Box2D world.\n * The function will not execute if the world is currently locked.\n * @throws {Error} Throws an assertion error if the world is locked when this function is called.\n */\nexport function b2World_EnableContinuous(worldId, flag)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.enableContinuous = flag;\n}\n\n/**\n * @function b2World_SetRestitutionThreshold\n * @summary Sets the restitution threshold for a Box2D world.\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} value - The restitution threshold value to set.\n * @returns {void}\n * @description\n * Sets the restitution threshold for collision response in the specified Box2D world.\n * The value is clamped between 0 and Number.MAX_VALUE. The function will not execute\n * if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetRestitutionThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.restitutionThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * @function b2World_SetHitEventThreshold\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {number} value - The new hit event threshold value to set\n * @returns {void}\n * @description\n * Sets the hit event threshold for a Box2D world. The value is clamped between 0 and Number.MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if the world is locked\n */\nexport function b2World_SetHitEventThreshold(worldId, value)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.hitEventThreshold = Math.max(0, Math.min(value, Number.MAX_VALUE));\n}\n\n/**\n * Sets the contact tuning parameters for a Box2D world.\n * @function b2World_SetContactTuning\n * @param {b2WorldId} worldId - The identifier for the Box2D world.\n * @param {number} hertz - The frequency for contact constraint solving.\n * @param {number} dampingRatio - The damping ratio for contact constraint solving.\n * @param {number} pushOut - The velocity used for contact separation.\n * @returns {void}\n * @description\n * Sets three contact-related parameters for physics simulation: the constraint frequency (hertz),\n * damping ratio, and push-out velocity. All input parameters are clamped between 0 and MAX_VALUE.\n * The function will not execute if the world is locked.\n * @throws {Error} Throws an assertion error if attempting to modify a locked world.\n */\nexport function b2World_SetContactTuning(worldId, hertz, dampingRatio, pushOut)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n world.contactHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.contactDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n world.contactPushoutVelocity = b2ClampFloat(pushOut, 0.0, Number.MAX_VALUE);\n}\n\nexport function b2World_SetJointTuning(worldId, hertz, dampingRatio)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n world.jointHertz = b2ClampFloat(hertz, 0.0, Number.MAX_VALUE);\n world.jointDampingRatio = b2ClampFloat(dampingRatio, 0.0, Number.MAX_VALUE);\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats(worldId)\n{\n // This function writes to a file, which is not directly applicable in JS.\n // You might want to modify this to return a string or object with the memory stats instead.\n console.error(\"Memory stats not implemented\");\n}\n\nfunction TreeQueryCallback(proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // B2_MAYBE_UNUSED(proxyId);\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\nclass WorldQueryContext\n{\n constructor(world = null, fcn = null, filter = null, userContext = null)\n {\n this.world = world;\n this.fcn = fcn;\n this.filter = filter;\n this.userContext = userContext;\n \n }\n}\n\n/**\n * @function b2World_OverlapAABB\n * @summary Queries an AABB region in the physics world for overlapping fixtures\n * @param {b2WorldId} worldId - The ID of the physics world to query\n * @param {b2AABB} aabb - The axis-aligned bounding box defining the query region\n * @param {b2QueryFilter} filter - Filter settings to control which fixtures are included\n * @param {b2OverlapResultFcn} fcn - Callback function that receives each overlapping fixture\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs a broadphase query using the world's dynamic tree to find all fixtures\n * that overlap with the given AABB. For each overlapping fixture that passes the\n * filter, the callback function is invoked.\n * @throws {Error} Throws an assertion error if the world is locked or if the AABB is invalid\n */\nexport function b2World_OverlapAABB(worldId, aabb, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2AABB_IsValid(aabb));\n\n const worldContext = new WorldQueryContext(world, fcn, filter, context);\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeQueryCallback, worldContext);\n }\n \n}\n\nfunction TreeOverlapCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return true;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n\n const input = new b2DistanceInput();\n input.proxyA = worldContext.proxy;\n input.proxyB = b2MakeShapeDistanceProxy(shape);\n input.transformA = worldContext.transform;\n input.transformB = transform;\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > 0.0)\n {\n return true;\n }\n\n const id = new b2ShapeId(shape.id + 1, world.worldId, shape.revision);\n const result = worldContext.fcn(id, worldContext.userContext);\n\n return result;\n}\n\n/**\n * @function b2World_OverlapCircle\n * @summary Tests for overlaps between a circle shape and all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Circle} circle - The circle shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation transform of the circle\n * @param {b2QueryFilter} filter - Filtering options for the overlap test\n * @param {function} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Performs broad-phase AABB queries to find potential overlaps between the given circle\n * and all shapes in the world that match the filter criteria. For each potential overlap,\n * the callback function is invoked with the overlap details.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid values.\n */\nexport function b2World_OverlapCircle(worldId, circle, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCircleAABB(circle, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(circle.center, 1, circle.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapCapsule\n * @summary Performs overlap queries for a capsule shape against all shapes in the world.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Capsule} capsule - The capsule shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the capsule\n * @param {b2QueryFilter} filter - Filtering options for the query\n * @param {b2OverlapResultFcn} fcn - Callback function that handles overlap results\n * @param {*} context - User context data passed to the callback function\n * @description\n * Tests a capsule shape against all shapes in the world that pass the filter criteria.\n * For each potential overlap, calls the provided callback function.\n * Uses a broad phase tree structure to efficiently find potential overlaps.\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * contains invalid position/rotation values.\n */\nexport function b2World_OverlapCapsule(worldId, capsule, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputeCapsuleAABB(capsule, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(capsule.center, 2, capsule.radius);\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\n/**\n * @function b2World_OverlapPolygon\n * @description\n * Performs overlap queries for a polygon shape against all shapes in the physics world\n * that match the provided filter criteria.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Polygon} polygon - The polygon shape to test for overlaps\n * @param {b2Transform} transform - The position and rotation of the polygon\n * @param {b2QueryFilter} filter - Filtering criteria for the overlap test\n * @param {b2OverlapResultFcn} fcn - Callback function to handle overlap results\n * @param {void} context - User data passed to the callback function\n * @throws {Error} Throws an assertion error if the world is locked or if the transform\n * components are invalid\n */\nexport function b2World_OverlapPolygon(worldId, polygon, transform, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(transform.p));\n console.assert(b2Rot_IsValid(transform.q));\n\n const aabb = b2ComputePolygonAABB(polygon, transform);\n const worldContext = new WorldOverlapContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.proxy = b2MakeProxy(polygon.vertices, polygon.count, polygon.radius),\n worldContext.transform = transform;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_Query(world.broadPhase.trees[i], aabb, filter.maskBits, TreeOverlapCallback, worldContext);\n }\n}\n\nfunction RayCastCallback(input, proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) === 0 || (shapeFilter.maskBits & queryFilter.categoryBits) === 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2RayCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n\n // The user may return -1 to skip this shape\n if (fraction >= 0.0 && fraction <= 1.0)\n {\n worldContext.fraction = fraction;\n }\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastRay\n * @description\n * Performs a ray cast operation in the physics world to detect intersections between\n * a ray and physics bodies.\n * @param {b2WorldId} worldId - The ID of the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filtering options for the ray cast\n * @param {b2CastResultFcn} fcn - Callback function to handle ray cast results\n * @param {void} context - User context data passed to the callback\n * @returns {b2TreeStats}\n * @throws {Error} Throws assertion error if world is locked\n * @throws {Error} Throws assertion error if origin or translation vectors are invalid\n */\nexport function b2World_CastRay(worldId, origin, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction === 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n// This callback finds the closest hit. This is the most common callback used in games.\nfunction b2RayCastClosestFcn(shapeId, point, normal, fraction, context)\n{\n const rayResult = context;\n rayResult.shapeId = shapeId;\n rayResult.point = point;\n rayResult.normal = normal;\n rayResult.fraction = fraction;\n rayResult.hit = true;\n\n return fraction;\n}\n\n/**\n * Performs a ray cast operation to find the closest intersection in the physics world.\n * @function b2World_CastRayClosest\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Vec2} origin - The starting point of the ray\n * @param {b2Vec2} translation - The direction and length of the ray\n * @param {b2QueryFilter} filter - Filter settings for the ray cast\n * @returns {b2RayResult} Information about the closest intersection found\n * @description\n * Casts a ray through the physics world and returns information about the closest\n * intersection. The ray is defined by an origin point and a translation vector.\n * The operation checks all body types in the broad phase using a dynamic tree\n * structure.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * origin/translation vectors are invalid\n */\nexport function b2World_CastRayClosest(worldId, origin, translation, filter)\n{\n const result = new b2RayResult();\n\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return result;\n }\n\n console.assert(b2Vec2_IsValid(origin));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2RayCastInput();\n input.origin = origin;\n input.translation = translation;\n input.maxFraction = 1.0;\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = b2RayCastClosestFcn;\n worldContext.fraction = 1.0;\n worldContext.userContext = result;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_RayCast(world.broadPhase.trees[i], input, filter.maskBits, RayCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return result;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n\n return result;\n}\n\nfunction ShapeCastCallback(input, proxyId, shapeId, context)\n{\n const worldContext = context;\n const world = worldContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n const shapeFilter = shape.filter;\n const queryFilter = worldContext.filter;\n\n if ((shapeFilter.categoryBits & queryFilter.maskBits) == 0 || (shapeFilter.maskBits & queryFilter.categoryBits) == 0)\n {\n return input.maxFraction;\n }\n\n const body = b2GetBody(world, shape.bodyId);\n const transform = b2GetBodyTransformQuick(world, body);\n const output = b2ShapeCastShape(input, shape, transform);\n\n if (output.hit)\n {\n const id = new b2ShapeId(shapeId + 1, world.worldId, shape.revision);\n const fraction = worldContext.fcn(id, output.point, output.normal, output.fraction, worldContext.userContext);\n worldContext.fraction = fraction;\n\n return fraction;\n }\n\n return input.maxFraction;\n}\n\n/**\n * @function b2World_CastCircle\n * @summary Performs a shape cast of a circle through the physics world.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Circle} circle - The circle shape to cast\n * @param {b2Transform} originTransform - The initial transform of the circle\n * @param {b2Vec2} translation - The displacement vector for the cast\n * @param {b2QueryFilter} filter - Filtering options for the cast\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User data passed to the callback function\n * @description\n * Casts a circle shape through the physics world from its initial position\n * along a translation vector, detecting collisions with other shapes. The cast\n * is performed against all body types in the broad phase, stopping if a collision\n * occurs at fraction 0.\n * @throws {Error} Throws an assertion error if the world is locked or if the\n * transform position, rotation, or translation vectors are invalid.\n */\nexport function b2World_CastCircle(worldId, circle, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, circle.center) ];\n input.count = 1;\n input.radius = circle.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastCapsule\n * @description\n * Performs a shape cast of a capsule through the physics world, detecting collisions\n * along the specified translation path.\n * @param {b2WorldId} worldId - The identifier for the physics world\n * @param {b2Capsule} capsule - The capsule shape to cast\n * @param {b2Transform} originTransform - The initial transform of the capsule, containing position (p) and rotation (q)\n * @param {b2Vec2} translation - The translation vector defining the cast path\n * @param {b2QueryFilter} filter - Filter settings for the cast operation\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {void} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastCapsule(worldId, capsule, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = [ b2TransformPoint(originTransform, capsule.center1), b2TransformPoint(originTransform, capsule.center2) ];\n input.count = 2;\n input.radius = capsule.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_CastPolygon\n * @description\n * Performs a shape cast of a polygon through the physics world, detecting collisions along the way.\n * @param {b2WorldId} worldId - ID of the physics world\n * @param {b2Polygon} polygon - The polygon shape to cast\n * @param {b2Transform} originTransform - Initial transform of the polygon, containing position and rotation\n * @param {b2Vec2} translation - The displacement vector to cast the polygon along\n * @param {b2QueryFilter} filter - Filter to determine which fixtures to check against\n * @param {b2CastResultFcn} fcn - Callback function to handle cast results\n * @param {*} context - User context data passed to the callback function\n * @throws {Error} Throws assertion error if world is locked or if transform/translation vectors are invalid\n */\nexport function b2World_CastPolygon(worldId, polygon, originTransform, translation, filter, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked == false);\n\n if (world.locked)\n {\n return;\n }\n\n console.assert(b2Vec2_IsValid(originTransform.p));\n console.assert(b2Rot_IsValid(originTransform.q));\n console.assert(b2Vec2_IsValid(translation));\n\n const input = new b2ShapeCastInput();\n input.points = polygon.vertices.map(vertex => b2TransformPoint(originTransform, vertex));\n input.count = polygon.count;\n input.radius = polygon.radius;\n input.translation = translation;\n input.maxFraction = 1.0;\n\n const worldContext = new WorldRayCastContext();\n worldContext.world = world;\n worldContext.fcn = fcn;\n worldContext.filter = filter;\n worldContext.fraction = 1.0;\n worldContext.userContext = context;\n\n for (let i = 0; i < b2BodyType.b2_bodyTypeCount; ++i)\n {\n b2DynamicTree_ShapeCast(world.broadPhase.trees[i], input, filter.maskBits, ShapeCastCallback, worldContext);\n\n if (worldContext.fraction == 0.0)\n {\n return;\n }\n\n input.maxFraction = worldContext.fraction;\n }\n}\n\n/**\n * @function b2World_SetPreSolveCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance\n * @param {b2PreSolveFcn} fcn - The pre-solve callback function to be executed\n * @param {void} context - User data pointer passed to the callback function\n * @returns {void}\n * @description\n * Sets a callback function that is invoked before the physics solver runs.\n * The callback receives the provided context pointer when executed.\n */\nexport function b2World_SetPreSolveCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.preSolveFcn = fcn;\n world.preSolveContext = context;\n}\n\n/**\n * @summary Sets a custom filter callback for a Box2D world.\n * @function b2World_SetCustomFilterCallback\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2CustomFilterFcn} fcn - The custom filter callback function.\n * @param {void} context - A pointer to user-defined context data.\n * @returns {void}\n * @description\n * Sets a custom filter callback function for a Box2D world instance. The callback\n * can be used to implement custom collision filtering logic. The context parameter\n * allows passing additional data to the callback function.\n */\nexport function b2World_SetCustomFilterCallback(worldId, fcn, context)\n{\n const world = b2GetWorldFromId(worldId);\n world.customFilterFcn = fcn;\n world.customFilterContext = context;\n}\n\n/**\n * @summary Sets the gravity vector for a Box2D world.\n * @function b2World_SetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @param {b2Vec2} gravity - The gravity vector to apply to the world. Defaults to (0,0).\n * @returns {void}\n * @description\n * Updates the gravity vector of the specified Box2D world. The gravity vector\n * defines the global acceleration applied to all dynamic bodies in the world.\n */\nexport function b2World_SetGravity(worldId, gravity)\n{\n const world = b2GetWorldFromId(worldId);\n world.gravity = gravity;\n}\n\n/**\n * @summary Gets the gravity vector from a Box2D world instance.\n * @function b2World_GetGravity\n * @param {b2WorldId} worldId - The identifier for the Box2D world instance.\n * @returns {b2Vec2} The gravity vector of the world. A 2D vector with x and y components.\n * @description\n * Retrieves the current gravity vector from the specified Box2D world instance.\n * The gravity vector represents the global gravity force applied to all dynamic bodies in the world.\n */\nexport function b2World_GetGravity(worldId)\n{\n const world = b2GetWorldFromId(worldId);\n\n return world.gravity;\n}\n\nclass ExplosionContext\n{\n constructor(world, position, radius, magnitude)\n {\n this.world = world;\n this.position = position;\n this.radius = radius;\n this.magnitude = magnitude;\n }\n}\n\nfunction ExplosionCallback(proxyId, shapeId, context)\n{\n // B2_MAYBE_UNUSED(proxyId);\n const explosionContext = context;\n const world = explosionContext.world;\n\n // b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n\n // b2CheckId(world.bodyArray, shape.bodyId);\n const body = world.bodyArray[shape.bodyId];\n\n if (body.type === b2BodyType.b2_kinematicBody)\n {\n return true;\n }\n\n b2WakeBody(world, body);\n\n if (body.setIndex !== b2SetType.b2_awakeSet)\n {\n return true;\n }\n\n const transform = b2GetBodyTransformQuick(world, body);\n const input = new b2DistanceInput();\n input.proxyA = b2MakeShapeDistanceProxy(shape);\n input.proxyB = b2MakeProxy([ explosionContext.position ], 1, 0.0);\n input.transformA = transform;\n input.transformB = new b2Transform(new b2Vec2(0, 0), new b2Rot(1, 0));\n input.useRadii = true;\n\n const cache = new b2DistanceCache();\n const output = b2ShapeDistance(cache, input, null, 0);\n\n if (output.distance > explosionContext.radius)\n {\n return true;\n }\n\n let closestPoint = output.pointA;\n\n if (output.distance === 0.0)\n {\n const localCentroid = b2GetShapeCentroid(shape);\n closestPoint = b2TransformPoint(transform, localCentroid);\n }\n\n const falloff = 0.4;\n const perimeter = b2GetShapePerimeter(shape);\n const magnitude = explosionContext.magnitude * perimeter * (1.0 - falloff * output.distance / explosionContext.radius);\n const direction = b2Normalize(b2Sub(closestPoint, explosionContext.position));\n const impulse = b2MulSV(magnitude, direction);\n\n const localIndex = body.localIndex;\n const set = world.solverSetArray[b2SetType.b2_awakeSet];\n console.assert(0 <= localIndex && localIndex < set.states.count);\n const state = set.states.data[localIndex];\n const bodySim = set.sims.data[localIndex];\n\n state.linearVelocity = b2MulAdd(state.linearVelocity, bodySim.invMass, impulse);\n state.angularVelocity += bodySim.invInertia * b2Cross(b2Sub(closestPoint, bodySim.center), impulse);\n\n return true;\n}\n\n/**\n * @function b2World_Explode\n * @summary Creates an explosion effect that applies forces to nearby dynamic bodies\n * @param {b2WorldId} worldId - The ID of the Box2D world\n * @param {b2Vec2} position - The center point of the explosion\n * @param {number} radius - The radius of the explosion effect\n * @param {number} magnitude - The force magnitude of the explosion\n * @returns {void}\n * @description\n * Creates a circular explosion centered at the given position that applies radial forces\n * to dynamic bodies within the explosion radius. The explosion force decreases with\n * distance from the center point.\n * @throws {Error} Throws assertion errors if:\n * - position is invalid\n * - radius is invalid or <= 0\n * - magnitude is invalid\n * - world is locked\n */\nexport function b2World_Explode(worldId, position, radius, magnitude)\n{\n console.assert(b2Vec2_IsValid(position));\n console.assert(b2IsValid(radius) && radius > 0.0);\n console.assert(b2IsValid(magnitude));\n const world = b2GetWorldFromId(worldId);\n console.assert(world.locked === false);\n\n if (world.locked)\n {\n return;\n }\n\n const explosionContext = new ExplosionContext(world, position, radius, magnitude);\n const aabb = new b2AABB(position.x - radius, position.y - radius, position.x + radius, position.y + radius);\n\n b2DynamicTree_Query(\n world.broadPhase.trees[b2BodyType.b2_dynamicBody],\n aabb,\n B2_DEFAULT_MASK_BITS,\n ExplosionCallback,\n explosionContext\n );\n}\n\nfunction b2GetRootIslandId(world, islandId)\n{\n if (islandId === B2_NULL_INDEX)\n {\n return B2_NULL_INDEX;\n }\n\n let rootId = islandId;\n let rootIsland = world.islandArray[islandId];\n\n while (rootIsland.parentIsland !== B2_NULL_INDEX)\n {\n const parent = world.islandArray[rootIsland.parentIsland];\n rootId = rootIsland.parentIsland;\n rootIsland = parent;\n }\n\n return rootId;\n}\n\nexport function b2CheckId(a, id)\n{\n console.assert( 0 <= id && id < a.length && a[id].id == id );\n}\n\nexport function b2CheckIndex(a, i)\n{\n if (Array.isArray(a))\n { console.assert(0 <= i && i < a.length); }\n else\n { console.assert(0 <= i && i < a.count); }\n}\n\nexport function b2ValidateConnectivity(world)\n{\n if (!b2Validation) { return; }\n\n const bodyCapacity = world.bodyArray.length;\n\n for (let bodyIndex = 0; bodyIndex < bodyCapacity; ++bodyIndex)\n {\n const body = world.bodyArray[bodyIndex];\n\n if (body.id === B2_NULL_INDEX)\n {\n // b2ValidateFreeId(world.bodyIdPool, bodyIndex);\n continue;\n }\n\n console.assert(bodyIndex === body.id);\n\n const bodyIslandId = b2GetRootIslandId(world, body.islandId);\n const bodySetIndex = body.setIndex;\n\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n const contact = world.contactArray[contactId];\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n\n if (touching && (contact.flags & b2ContactFlags.b2_contactSensorFlag) === 0)\n {\n if (bodySetIndex !== b2SetType.b2_staticSet)\n {\n const contactIslandId = b2GetRootIslandId(world, contact.islandId);\n console.assert(contactIslandId === bodyIslandId);\n }\n }\n else\n {\n console.assert(contact.islandId === B2_NULL_INDEX);\n }\n\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n const edgeIndex = jointKey & 1;\n\n const joint = world.jointArray[jointId];\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (bodySetIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n else if (bodySetIndex === b2SetType.b2_staticSet)\n {\n if (otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.islandId === B2_NULL_INDEX);\n }\n }\n else\n {\n const jointIslandId = b2GetRootIslandId(world, joint.islandId);\n console.assert(jointIslandId === bodyIslandId);\n }\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n}\n\nexport function b2ValidateSolverSets(world)\n{\n if (!b2Validation) { return; }\n\n let activeSetCount = 0;\n let totalBodyCount = 0;\n let totalJointCount = 0;\n let totalContactCount = 0;\n let totalIslandCount = 0;\n\n // Validate all solver sets\n const setCount = world.solverSetArray.length;\n\n for (let setIndex = 0; setIndex < setCount; ++setIndex)\n {\n const set = world.solverSetArray[setIndex];\n\n if (set.setIndex !== B2_NULL_INDEX)\n {\n activeSetCount += 1;\n\n if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(set.contacts.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(set.sims.count === set.states.count);\n console.assert(set.joints.count === 0);\n }\n else if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n else\n {\n console.assert(set.states.count === 0);\n }\n\n // Validate bodies\n {\n const bodies = world.bodyArray;\n console.assert(set.sims.count >= 0);\n totalBodyCount += set.sims.count;\n\n for (let i = 0; i < set.sims.count; ++i)\n {\n const bodySim = set.sims.data[i];\n\n const bodyId = bodySim.bodyId;\n b2CheckIndex(bodies, bodyId);\n const body = bodies[bodyId];\n console.assert(body.setIndex === setIndex);\n console.assert(body.localIndex === i);\n\n // console.assert(body.revision === body.revision);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(body.headContactKey === B2_NULL_INDEX);\n }\n\n // Validate body shapes\n let prevShapeId = B2_NULL_INDEX;\n let shapeId = body.headShapeId;\n\n while (shapeId !== B2_NULL_INDEX)\n {\n b2CheckId(world.shapeArray, shapeId);\n const shape = world.shapeArray[shapeId];\n console.assert(shape.prevShapeId === prevShapeId);\n\n if (setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(shape.proxyKey === B2_NULL_INDEX);\n }\n else if (setIndex === b2SetType.b2_staticSet)\n {\n console.assert(B2_PROXY_TYPE(shape.proxyKey) === b2BodyType.b2_staticBody);\n }\n else\n {\n const proxyType = B2_PROXY_TYPE(shape.proxyKey);\n console.assert(proxyType === b2BodyType.b2_kinematicBody || proxyType === b2BodyType.b2_dynamicBody);\n }\n\n prevShapeId = shapeId;\n shapeId = shape.nextShapeId;\n }\n\n // Validate body contacts\n let contactKey = body.headContactKey;\n\n while (contactKey !== B2_NULL_INDEX)\n {\n const contactId = contactKey >> 1;\n const edgeIndex = contactKey & 1;\n\n b2CheckIndex(world.contactArray, contactId);\n const contact = world.contactArray[contactId];\n console.assert(contact.setIndex !== b2SetType.b2_staticSet);\n console.assert(contact.edges[0].bodyId === bodyId || contact.edges[1].bodyId === bodyId);\n contactKey = contact.edges[edgeIndex].nextKey;\n }\n\n // Validate body joints\n let jointKey = body.headJointKey;\n\n while (jointKey !== B2_NULL_INDEX)\n {\n const jointId = jointKey >> 1;\n\n // console.warn(\"jointKey \" + jointKey);\n const edgeIndex = jointKey & 1;\n\n b2CheckIndex(world.jointArray, jointId);\n const joint = world.jointArray[jointId];\n\n // PJB: not sure about this...\n console.assert(joint.jointId == jointId);\n\n const otherEdgeIndex = edgeIndex ^ 1;\n\n b2CheckIndex(world.bodyArray, joint.edges[otherEdgeIndex].bodyId);\n const otherBody = world.bodyArray[joint.edges[otherEdgeIndex].bodyId];\n\n if (setIndex === b2SetType.b2_disabledSet || otherBody.setIndex === b2SetType.b2_disabledSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_disabledSet);\n }\n else if (setIndex === b2SetType.b2_staticSet && otherBody.setIndex === b2SetType.b2_staticSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_staticSet);\n }\n else if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n }\n else if (setIndex >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(joint.setIndex === setIndex);\n }\n\n const jointSim = b2GetJointSim(world, joint);\n console.assert(jointSim.jointId === jointId);\n console.assert(jointSim.bodyIdA === joint.edges[0].bodyId);\n console.assert(jointSim.bodyIdB === joint.edges[1].bodyId);\n\n jointKey = joint.edges[edgeIndex].nextKey;\n }\n }\n }\n\n // Validate contacts\n {\n const contacts = world.contactArray;\n console.assert(set.contacts.count >= 0);\n totalContactCount += set.contacts.count;\n\n for (let i = 0; i < set.contacts.count; ++i)\n {\n const contactSim = set.contacts.data[i];\n console.assert(0 <= contactSim.contactId && contactSim.contactId < contacts.length);\n const contact = contacts[contactSim.contactId];\n\n if (setIndex === b2SetType.b2_awakeSet)\n {\n console.assert(contactSim.manifold.pointCount === 0 ||\n (contactSim.simFlags & b2ContactSimFlags.b2_simStartedTouching) !== 0);\n }\n console.assert(contact.setIndex === setIndex);\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n console.assert(contact.localIndex === i);\n }\n }\n\n // Validate joints\n {\n const joints = world.jointArray;\n console.assert(set.joints.count >= 0);\n totalJointCount += set.joints.count;\n\n for (let i = 0; i < set.joints.count; ++i)\n {\n const jointSim = set.joints.data[i];\n console.assert(0 <= jointSim.jointId && jointSim.jointId < joints.length);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === setIndex);\n console.assert(joint.colorIndex === B2_NULL_INDEX);\n console.assert(joint.localIndex === i);\n }\n }\n\n // Validate islands\n {\n const islands = world.islandArray;\n console.assert(set.islands.count >= 0);\n totalIslandCount += set.islands.count;\n\n for (let i = 0; i < set.islands.count; ++i)\n {\n const islandSim = set.islands.data[i];\n console.assert(0 <= islandSim.islandId && islandSim.islandId < islands.length);\n const island = islands[islandSim.islandId];\n console.assert(island.setIndex === setIndex);\n console.assert(island.localIndex === i);\n }\n }\n }\n else\n {\n console.assert(set.sims.count === 0);\n console.assert(set.contacts.count === 0);\n console.assert(set.joints.count === 0);\n console.assert(set.islands.count === 0);\n console.assert(set.states.count === 0);\n }\n }\n\n const setIdCount = b2GetIdCount(world.solverSetIdPool);\n console.assert(activeSetCount === setIdCount);\n\n const bodyIdCount = b2GetIdCount(world.bodyIdPool);\n console.assert(totalBodyCount === bodyIdCount);\n\n const islandIdCount = b2GetIdCount(world.islandIdPool);\n console.assert(totalIslandCount === islandIdCount);\n\n // Validate constraint graph\n for (let colorIndex = 0; colorIndex < b2_graphColorCount; ++colorIndex)\n {\n const color = world.constraintGraph.colors[colorIndex];\n\n {\n const contacts = world.contactArray;\n console.assert(color.contacts.count >= 0);\n totalContactCount += color.contacts.count;\n\n for (let i = 0; i < color.contacts.count; ++i)\n {\n const contactSim = color.contacts.data[i];\n b2CheckIndex(contacts, contactSim.contactId);\n const contact = contacts[contactSim.contactId];\n console.assert(contactSim.manifold.pointCount > 0 ||\n (contactSim.simFlags & (b2ContactSimFlags.b2_simStoppedTouching | b2ContactSimFlags.b2_simDisjoint)) !== 0);\n console.assert(contact.setIndex === b2SetType.b2_awakeSet);\n console.assert(contact.colorIndex === colorIndex);\n console.assert(contact.localIndex === i);\n\n const bodyIdA = contact.edges[0].bodyId;\n const bodyIdB = contact.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n\n {\n const joints = world.jointArray;\n console.assert(color.joints.count >= 0);\n totalJointCount += color.joints.count;\n\n for (let i = 0; i < color.joints.count; ++i)\n {\n const jointSim = color.joints.data[i];\n b2CheckIndex(joints, jointSim.jointId);\n const joint = joints[jointSim.jointId];\n console.assert(joint.setIndex === b2SetType.b2_awakeSet);\n console.assert(joint.colorIndex === colorIndex);\n console.assert(joint.localIndex === i);\n\n const bodyIdA = joint.edges[0].bodyId;\n const bodyIdB = joint.edges[1].bodyId;\n b2CheckIndex(world.bodyArray, bodyIdA);\n b2CheckIndex(world.bodyArray, bodyIdB);\n\n if (colorIndex < b2_overflowIndex)\n {\n const bodyA = world.bodyArray[bodyIdA];\n const bodyB = world.bodyArray[bodyIdB];\n console.assert(b2GetBit(color.bodySet, bodyIdA) === (bodyA.type !== b2BodyType.b2_staticBody));\n console.assert(b2GetBit(color.bodySet, bodyIdB) === (bodyB.type !== b2BodyType.b2_staticBody));\n }\n }\n }\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(totalContactCount === contactIdCount);\n console.assert(totalContactCount === world.broadPhase.pairSet.size, `totalContactCount ${totalContactCount} != pairSet.size ${world.broadPhase.pairSet.size}`);\n\n const jointIdCount = b2GetIdCount(world.jointIdPool);\n console.assert(totalJointCount === jointIdCount);\n}\n\nfunction b2GetBit(bitSet, bitIndex)\n{\n const blockIndex = Math.floor(bitIndex / 64);\n\n if (blockIndex >= bitSet.blockCount)\n {\n return false;\n }\n\n return (bitSet.bits[blockIndex] & (BigInt(1) << BigInt(bitIndex % 64))) !== BigInt(0);\n}\n\nexport function b2ValidateContacts(world)\n{\n if (!b2Validation) { return; }\n \n const contactCount = world.contactArray.length;\n console.assert(contactCount >= b2GetIdCapacity(world.contactIdPool));\n let allocatedContactCount = 0;\n\n for (let contactIndex = 0; contactIndex < contactCount; ++contactIndex)\n {\n const contact = world.contactArray[contactIndex];\n\n if (contact.contactId === B2_NULL_INDEX)\n {\n continue;\n }\n\n console.assert(contact.contactId === contactIndex);\n\n allocatedContactCount += 1;\n\n const touching = (contact.flags & b2ContactFlags.b2_contactTouchingFlag) !== 0;\n const sensorTouching = (contact.flags & b2ContactFlags.b2_contactSensorTouchingFlag) !== 0;\n const isSensor = (contact.flags & b2ContactFlags.b2_contactSensorFlag) !== 0;\n\n console.assert(touching === false || sensorTouching === false);\n console.assert(touching === false || isSensor === false);\n\n const setId = contact.setIndex;\n\n if (setId === b2SetType.b2_awakeSet)\n {\n if (touching && isSensor === false)\n {\n console.assert(0 <= contact.colorIndex && contact.colorIndex < b2_graphColorCount);\n }\n else\n {\n console.assert(contact.colorIndex === B2_NULL_INDEX);\n }\n }\n else if (setId >= b2SetType.b2_firstSleepingSet)\n {\n console.assert(touching === true && isSensor === false);\n }\n else\n {\n console.assert(touching === false && setId === b2SetType.b2_disabledSet);\n }\n\n const contactSim = b2GetContactSim(world, contact);\n console.assert(contactSim.contactId === contactIndex);\n console.assert(contactSim._bodyIdA === contact.edges[0].bodyId, contact);\n console.assert(contactSim._bodyIdB === contact.edges[1].bodyId);\n\n const simTouching = (contactSim.simFlags & b2ContactSimFlags.b2_simTouchingFlag) !== 0;\n\n console.assert(touching == simTouching || sensorTouching == simTouching, `failed: ${touching} or ${sensorTouching} == ${simTouching}`);\n console.assert(0 <= contactSim.manifold.pointCount && contactSim.manifold.pointCount <= 2);\n }\n\n const contactIdCount = b2GetIdCount(world.contactIdPool);\n console.assert(allocatedContactCount === contactIdCount);\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nexport const b2_maxWorkers = 1;\n\nexport {\n b2SetType, b2World,\n b2CreateWorldArray,\n b2GetWorldFromId, b2GetWorld, b2GetWorldLocked,\n b2CreateWorld, b2World_Step, b2DestroyWorld,\n b2World_Draw,\n b2World_OverlapAABB, b2World_OverlapCapsule, b2World_OverlapCircle, b2World_OverlapPolygon,\n b2World_Explode,\n b2World_CastCapsule, b2World_CastCircle, b2World_CastPolygon, b2World_CastRay, b2World_CastRayClosest,\n b2World_GetBodyEvents, b2World_GetContactEvents, b2World_GetGravity, b2World_GetSensorEvents,\n b2World_SetContactTuning, b2World_SetJointTuning, b2World_SetPreSolveCallback, b2World_SetCustomFilterCallback,\n b2World_SetGravity, b2World_SetHitEventThreshold, b2World_SetRestitutionThreshold,\n b2World_IsValid, b2Joint_IsValid,\n b2World_IsSleepingEnabled,\n b2World_EnableSleeping, b2World_EnableContinuous, b2World_IsContinuousEnabled, b2World_GetRestitutionThreshold,\n b2World_GetHitEventThreshold, b2World_EnableWarmStarting, b2World_IsWarmStartingEnabled,\n b2ValidateConnectivity, b2ValidateSolverSets, b2ValidateContacts,\n b2CheckIndex, b2Body_IsValid, b2Chain_IsValid, b2Shape_IsValid,\n} from '../world_c.js';\n\n/**\n * @summary Gets the performance profile data for a Box2D world.\n * @function b2World_GetProfile\n * @param {b2WorldId} worldId - The identifier of the Box2D world.\n * @returns {b2Profile} A profile object containing performance metrics.\n * @description\n * This function returns performance profiling data for a Box2D world.\n * Not supported in Phaser Box2D JS implementation.\n * @throws {Error} Outputs a console warning indicating lack of support in Phaser Box2D JS.\n */\nexport function b2World_GetProfile()\n{\n console.warn(\"b2World_GetProfile not supported\");\n}\n\n/**\n * Gets the current counters from a Box2D world instance.\n * @function b2World_GetCounters\n * @param {b2WorldId} worldId - The ID of the Box2D world instance.\n * @returns {b2Counters} An object containing various Box2D performance counters.\n * @description\n * This function is not supported in the Phaser Box2D JS implementation and will\n * generate a console warning when called.\n */\nexport function b2World_GetCounters()\n{\n console.warn(\"b2World_GetCounters not supported\");\n}\n\n/**\n * @summary Dumps memory statistics for a Box2D world (Not supported in Phaser Box2D JS)\n * @function b2World_DumpMemoryStats\n * @param {b2WorldId} worldId - The identifier of the Box2D world\n * @returns {void}\n * @description\n * This function is a stub that displays a warning message indicating that memory statistics\n * dumping is not supported in the Phaser Box2D JavaScript implementation.\n */\nexport function b2World_DumpMemoryStats()\n{\n console.warn(\"b2World_DumpMemoryStats not supported\");\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { B2_MAX_POLYGON_VERTICES, b2Capsule, b2Circle } from './include/collision_h.js';\nimport { b2Add, b2Distance, b2RelativeAngle, b2Rot, b2MakeRot, b2Transform, b2Vec2 } from './include/math_functions_h.js';\nimport\n{\n b2BodyType,\n b2DefaultBodyDef,\n b2DefaultShapeDef,\n b2DefaultWorldDef,\n b2DistanceJointDef,\n b2HexColor,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\nimport { b2Body_GetRotation, b2Body_GetTransform, b2Body_SetTransform, b2Body_SetUserData, b2CreateBody, b2DestroyBody, b2GetBodyTransform } from './include/body_h.js';\nimport { b2CreateCapsuleShape, b2CreateCircleShape, b2CreatePolygonShape } from './include/shape_h.js';\nimport { b2CreateDistanceJoint, b2CreateMotorJoint, b2CreateMouseJoint, b2CreatePrismaticJoint, b2CreateRevoluteJoint, b2CreateWeldJoint, b2CreateWheelJoint } from './include/joint_h.js';\nimport { b2CreateWorld, b2CreateWorldArray, b2World_Step } from './include/world_h.js';\nimport { b2MakeBox, b2MakeOffsetBox, b2MakeOffsetPolygon, b2MakePolygon } from './include/geometry_h.js';\n\nimport { DYNAMIC } from './main.js';\nimport { b2ComputeHull } from './include/hull_h.js';\n\n/**\n * @namespace Physics\n */\n\n// local \n\nfunction setIfDef (obj, prop, value)\n{\n if (value !== undefined)\n {\n obj[ prop ] = value;\n\n return true;\n }\n\n return false;\n}\n\nexport const WorldSprites = new Map();\n\nlet SCALE = 30.0;\n\n/**\n * Set the scale of the Box2D World when converting from pixels to meters.\n *\n * @export\n * @param {number} scale\n */\nexport function SetWorldScale (scale)\n{\n SCALE = scale;\n}\n\n/**\n * Get the current scale of the Box2D World, as used when converting from pixels to meters.\n *\n * @export\n * @returns {number}\n */\nexport function GetWorldScale ()\n{\n return SCALE;\n}\n\n/**\n * Converts a single numerical value from meters to pixels.\n *\n * @export\n * @param {number} meters\n * @returns {number}\n */\nexport function mpx (meters)\n{\n return meters * SCALE;\n}\n\n/**\n * Converts a single numerical value from pixels to meters.\n *\n * @export\n * @param {number} pixels\n * @returns {number}\n */\nexport function pxm (pixels)\n{\n return pixels / SCALE;\n}\n\n/**\n * Converts the given x and y values from pixels to meters, stored in a new b2Vec2.\n *\n * @export\n * @param {number} x\n * @param {number} y\n * @returns {b2Vec2}\n */\nexport function pxmVec2 (x, y)\n{\n return new b2Vec2(x / SCALE, y / SCALE);\n}\n\n/**\n * Convets the given value in radians to a b2Rot object, used for Box2D rotations.\n *\n * @export\n * @param {number} radians\n * @returns {b2Rot}\n */\nexport function RotFromRad (radians)\n{\n return new b2Rot(Math.cos(-radians), Math.sin(-radians));\n}\n\n/**\n * Adds a Sprite Game Object to the given World, attaching it to the given Body.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {b2Body} body\n */\nexport function AddSpriteToWorld (worldId, sprite, body)\n{\n if (!WorldSprites.has(worldId))\n {\n WorldSprites.set(worldId, new Map());\n }\n\n WorldSprites.get(worldId).set(sprite, body);\n}\n\n/**\n * Removes a Sprite Game Object from the given World, optionally destroying the Body it was attached to.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @param {boolean} [destroyBody=false]\n */\nexport function RemoveSpriteFromWorld (worldId, sprite, destroyBody = false)\n{\n if (WorldSprites.has(worldId))\n {\n const worldMap = WorldSprites.get(worldId);\n const body = worldMap.get(sprite);\n\n if (body && destroyBody)\n {\n const bodyId = body.bodyId;\n b2DestroyBody(bodyId);\n }\n\n worldMap.delete(sprite);\n }\n}\n\n/**\n * Clears all Sprite to Body pairs.\n * Neither the Sprites nor the Bodies are destroyed.\n * The bodies remain in the world.\n *\n * @export\n * @param {number} worldId\n */\nexport function ClearWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).clear();\n }\n}\n\n/**\n * Returns the Body attached to the given Sprite in the given World.\n * Or `null` if no such pair exists.\n *\n * @export\n * @param {number} worldId\n * @param {Sprite} sprite\n * @returns {Sprite|null} Either the sprite, or `null`.\n */\nexport function GetBodyFromSprite (worldId, sprite)\n{\n if (WorldSprites.has(worldId))\n {\n return WorldSprites.get(worldId).get(sprite);\n }\n\n return null;\n}\n\n/**\n * Runs through all World-Sprite pairs and updates the Sprite positions and rotations to match the Body.\n * \n * @param {number} worldId \n */\nexport function UpdateWorldSprites (worldId)\n{\n if (WorldSprites.has(worldId))\n {\n WorldSprites.get(worldId).forEach((body, sprite) =>\n {\n BodyToSprite(body, sprite);\n });\n }\n}\n\n/**\n * Converts a Box2D Body's position and rotation to a Sprite's position and rotation.\n * \n * This is called automatically by `UpdateWorldSprites`.\n *\n * @export\n * @param {b2Body} body\n * @param {Sprite} sprite\n */\nexport function BodyToSprite (body, sprite)\n{\n const t = b2Body_GetTransform(body.bodyId);\n\n sprite.x = t.p.x * SCALE;\n sprite.y = -(t.p.y * SCALE);\n sprite.rotation = -Math.atan2(t.q.s, t.q.c);\n}\n\n/**\n * @typedef {Object} Sprite\n * @property {number} x - The x position of the sprite.\n * @property {number} y - The y position of the sprite.\n * @property {number} width - The width of the sprite.\n * @property {number} height - The height of the sprite.\n * @property {number} rotation - The rotation of the sprite in radians.\n * @property {number} [scaleX] - Optional horizontal scale of the sprite.\n * @property {number} [scaleY] - Optional vertical scale of the sprite.\n * @property {b2Vec2} [scale] - Optional scale vector of the sprite.\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {BoxPolygonConfig} data - Additional configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToBox (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateBoxPolygon({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * Creates a circle-shaped polygon and attaches it to a body based on the dimensions, position\n * and rotation of the given Sprite.\n * \n * @param {number} worldId - The World ID.\n * @param {Sprite} sprite - The Sprite object to read the data from.\n * @param {CircleConfig} data - Additional configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function SpriteToCircle (worldId, sprite, data)\n{\n const scaleX = sprite?.scaleX || sprite?.scale?.x || 1;\n const scaleY = sprite?.scaleY || sprite?.scale?.y || 1;\n\n const props = {\n worldId,\n type: DYNAMIC,\n size: pxmVec2((sprite.width * scaleX) / 2, (sprite.height * scaleY) / 2)\n };\n\n const body = CreateCircle({ ...props, ...data });\n\n b2Body_SetTransform(\n body.bodyId,\n pxmVec2(sprite.x, -sprite.y),\n RotFromRad(sprite.rotation)\n );\n\n return body;\n}\n\n/**\n * @typedef {Object} WorldConfig\n * @property {b2WorldDef} [worldDef] - World definition\n */\n\n/**\n * Creates a world and returns the ID.\n * @param {WorldConfig} data - Configuration for the world.\n * @returns {{worldId: b2WorldId}} The created world's ID.\n * @memberof Physics\n */\nexport function CreateWorld (data)\n{\n let worldDef = data.worldDef;\n\n if (!worldDef)\n {\n worldDef = b2DefaultWorldDef();\n }\n\n // make sure the world array has been created\n b2CreateWorldArray();\n const worldId = b2CreateWorld(worldDef);\n\n return { worldId: worldId };\n}\n\n/**\n * @typedef {Object} WorldStepConfig\n * @property {b2WorldId} worldId - The world ID value\n * @property {number} deltaTime - How long has it been since the last call (e.g. the value passed to a RAF update)\n * @property {number} [fixedTimeStep = 1/60] - Duration of the fixed timestep for the Physics simulation\n * @property {number} [subStepCount = 4] - Number of sub-steps performed per world step\n */\n\nlet _accumulator = 0;\n\n/**\n * Steps a physics world to match fixedTimeStep.\n * Returns the average time spent in the step function.\n * \n * @param {WorldConfig} data - Configuration for the world.\n * @returns {number} totalTime - Time spent processing the step function, in seconds.\n */\nexport function WorldStep (data)\n{\n let fixedTimeStep = data.fixedTimeStep;\n\n if (!fixedTimeStep)\n { fixedTimeStep = 1 / 60; }\n let subStepCount = data.subStepCount;\n\n if (!subStepCount)\n { subStepCount = 4; }\n\n const borrowedTime = fixedTimeStep * 2.0;\n _accumulator = Math.min(_accumulator + data.deltaTime, fixedTimeStep + borrowedTime);\n\n // try to catch-up if we've skipped some frames\n const catchUpMax = 2;\n let c = catchUpMax;\n\n // if we've been running below the fixedTimeStep, don't attempt to catch-up\n if (data.deltaTime > fixedTimeStep)\n {\n c = 0;\n }\n\n let totalTime = 0;\n\n // while we owe time, have some catch-up count remaining, and haven't used the entire fixedTimeStep yet...\n while (_accumulator >= fixedTimeStep && c-- >= 0 && totalTime < fixedTimeStep)\n {\n const start = performance.now();\n b2World_Step(data.worldId, fixedTimeStep, subStepCount);\n const end = performance.now();\n totalTime = (end - start) / 1000;\n _accumulator -= fixedTimeStep;\n }\n\n return totalTime;\n}\n\n/**\n * @typedef {Object} ChainConfig\n * @property {b2WorldId} worldId - ID for the world.\n * @property {b2BodyId} groundId - ID for the static ground to attach the chain ends to.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} firstLinkPosition - Position of the first link.\n * @property {b2Vec2} lastLinkPosition - Position of the last link.\n * @property {number} chainLinks - Number of links in the chain.\n * @property {number} linkLength - Length of each link\n * @property {number} [density] - Density of the links.\n * @property {number} [friction] - Friction of the links.\n * @property {any} [color] - Custom color for the links.\n * @property {number} [radius] - Radius for the circle 'caps' on each capsule link.\n * @property {boolean} fixEnds - Should the ends of the chain be fixed to the groundId object?\n */\n\n/**\n * @typedef {Object} BodyCapsule\n * @property {b2BodyId} bodyId - ID for the body to attach the capsule to.\n * @property {b2ShapeId} shapeId - ID for the shape to attach the capsule to.\n * @propery {b2Capsule} object - The capsule object to attach.\n */\n\n/**\n * Creates a chain of capsules with each one linked to the previous and next one.\n * @param {ChainConfig} data - Configuration for the chain.\n * @returns {BodyCapsule[]} A list of each link's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateChain (data)\n{\n const chainSpacing = b2Distance(data.firstLinkPosition, data.lastLinkPosition) / data.chainLinks;\n const type = data.type !== undefined ? data.type : b2BodyType.b2_dynamicBody;\n const density = data.density !== undefined ? data.density : 1.0;\n const friction = data.friction !== undefined ? data.friction : 0.5;\n const color = data.color !== undefined ? data.color : b2HexColor.b2_colorGold;\n const radius = data.radius !== undefined ? data.radius : 0.5;\n\n var lastLink = null;\n var position = b2Add(data.firstLinkPosition, new b2Vec2(data.linkLength, 0));\n\n const listLinks = [];\n\n for (let i = 0; i < data.chainLinks; i++)\n {\n // const link = CreateBoxPolygon({ worldId:world.worldId, type:b2BodyType.b2_dynamicBody, position:position, size:new b2Vec2(linkLength / 2,0.5), density:1.0, friction:0.2, groupIndex:-1, color:b2HexColor.b2_colorGold });\n const link = CreateCapsule({ worldId: data.worldId, type: type, position: position, center1: new b2Vec2(-data.linkLength / 2 + data.radius, 0), center2: new b2Vec2(data.linkLength / 2 - data.radius, 0), radius: radius, density: density, friction: friction, groupIndex: -1, color: color });\n listLinks.push(link);\n\n if (i == 0) // connect first link to solid\n {\n if (data.fixEnds)\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: link.bodyId,\n anchorA: data.firstLinkPosition,\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n }\n else // connect each link to the last one\n {\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: lastLink.bodyId,\n bodyIdB: link.bodyId,\n anchorA: new b2Vec2(data.linkLength / 2, 0),\n anchorB: new b2Vec2(-data.linkLength / 2, 0),\n });\n }\n lastLink = link;\n\n // Lay out all the pieces in a straight line overlapping each other if necessary\n position = b2Add(position, new b2Vec2(chainSpacing, 0));\n }\n\n if (data.fixEnds)\n {\n // connect the last link to solid\n CreateRevoluteJoint({\n worldId: data.worldId,\n bodyIdA: data.groundId,\n bodyIdB: lastLink.bodyId,\n anchorA: data.lastLinkPosition,\n anchorB: new b2Vec2(data.linkLength / 2, 0),\n });\n }\n\n return listLinks;\n}\n\n/**\n * @typedef {Object} CircleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the circle.\n * @property {b2BodyDef} [bodyDef] - Body definition for the circle.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the circle's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the circle.\n * @property {number} [groupIndex] - Collision filtering, group index for the circle.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this cirle in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this circle collide with?\n * @property {number} [density] - Density of the circle.\n * @property {number} [friction] - Friction of the circle.\n * @property {number} [restitution=0.1] - Restitution of the circle.\n * @property {any} [color] - Custom color for the circle.\n * @property {number} [radius] - Radius of the circle.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {boolean} [isSensor] - A sensor shape generates overlap events but never generates a collision response\n * @property {b2Vec2} [offset] - Offset of the circle's center when adding as a fixture.\n */\n\n/**\n * Creates a circle shape and attaches it to a body.\n * @param {CircleConfig} data - Configuration for the circle.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Circle}} The created circle's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCircle (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n setIfDef(shapeDef, \"isSensor\", data.isSensor);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n\n const ball = new b2Circle();\n setIfDef(ball, \"radius\", data.radius);\n\n if (data.bodyId)\n {\n setIfDef(ball, \"center\", data.offset);\n }\n\n const shapeId = b2CreateCircleShape(bodyId, shapeDef, ball);\n\n return { bodyId: bodyId, shapeId: shapeId, object: ball };\n}\n\n/**\n * @typedef {Object} CapsuleConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the capsule.\n * @property {b2BodyDef} [bodyDef] - Body definition for the capsule.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the capsule's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the capsule.\n * @property {number} [density] - Density of the capsule.\n * @property {number} [friction] - Friction of the capsule.\n * @property {number} [groupIndex] - Collision group index for the capsule.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {any} [color] - Custom color for the capsule.\n * @property {b2Vec2} [center1] - Center of the first circle of the capsule. Optional if 'height' is set.\n * @property {b2Vec2} [center2] - Center of the second circle of the capsule. Optional if 'height' is set.\n * @property {number} [radius] - Radius of the capsule's circles. Optional if 'width' is set.\n * @property {boolean} [fixedRotation] - Prevent rotation if set to true.\n * @property {number} [linearDamping] - Linear damping of velocity.\n * @property {number} [width] - The overall width of the capsule. If set replaces radius.\n * @property {number} [height] - The overall height of the capsule, including the start and end caps. If set replaces center1 and center2.\n */\n\n/**\n * Creates a capsule shape and attaches it to a body.\n * @param {CapsuleConfig} data - Configuration for the capsule.\n * @returns {BodyCapsule} The created capsule's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateCapsule (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const capsule = new b2Capsule();\n\n if (data.width)\n {\n data.radius = data.width / 2;\n }\n\n if (data.height)\n {\n data.radius = Math.min(data.radius, data.height / 2);\n data.center1 = new b2Vec2(0, -(data.height / 2));\n data.center2 = new b2Vec2(0, data.height / 2);\n }\n\n setIfDef(capsule, \"center1\", data.center1);\n setIfDef(capsule, \"center2\", data.center2);\n setIfDef(capsule, \"radius\", data.radius);\n const shapeId = b2CreateCapsuleShape(bodyId, shapeDef, capsule);\n\n return { bodyId: bodyId, shapeId: shapeId, object: capsule };\n}\n\n/**\n * @typedef {Object} BoxPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the box.\n * @property {b2BodyDef} [bodyDef] - Body definition for the box.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the box's center.\n * @property {boolean} [fixedRotation] - Prevent box from rotating?\n * @property {number} [linearDamping] - Damping for linear velocity.\n * @property {number} [angularDamping] - Damping for angular velocity.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the box.\n * @property {any} [userData] - The user data to associate with the body.\n * @property {number} [groupIndex] - Collision group index for the box.\n * @property {number} [categoryBits] - Collision filtering, what 'category' is this in?\n * @property {number} [maskBits] - Collision filtering, what 'categories' will this collide with?\n * @property {number} [density=1.0] - Density of the box.\n * @property {number} [friction=0.6] - Friction of the box.\n * @property {number} [restitution=0.1] - Restitution of the box.\n * @property {any} [color] - Custom color for the box.\n * @property {boolean} [preSolve] - Enable presolve callback for the circle.\n * @property {b2Vec2|number} size - Size of the box (either a b2Vec2 or a single number for square).\n */\n\n/**\n * Creates a box-shaped polygon and attaches it to a body.\n * @param {BoxPolygonConfig} data - Configuration for the box polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created box's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateBoxPolygon (data)\n{\n let bodyDef = data.bodyDef;\n\n if (!bodyDef)\n {\n bodyDef = b2DefaultBodyDef();\n }\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n setIfDef(bodyDef, \"fixedRotation\", data.fixedRotation);\n setIfDef(bodyDef, \"linearDamping\", data.linearDamping);\n setIfDef(bodyDef, \"angularDamping\", data.angularDamping);\n\n // if bodyId is in the data, this box is a fixture for the body specified\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n let shapeDef = data.shapeDef;\n\n if (!shapeDef)\n {\n shapeDef = b2DefaultShapeDef();\n }\n\n const userData = data.userData;\n\n if (userData)\n {\n b2Body_SetUserData(bodyId, data.userData);\n }\n\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef.filter, \"categoryBits\", data.categoryBits);\n setIfDef(shapeDef.filter, \"maskBits\", data.maskBits);\n setIfDef(shapeDef, \"customColor\", data.color);\n setIfDef(shapeDef, \"enablePreSolveEvents\", data.preSolve);\n\n // data.size can be a b2Vec2 or a number\n let box;\n\n if (data.size instanceof b2Vec2)\n {\n if (data.bodyId)\n {\n box = b2MakeOffsetBox(data.size.x, data.size.y, data.position, b2MakeRot(0));\n }\n else\n {\n box = b2MakeBox(data.size.x, data.size.y);\n }\n }\n else\n {\n box = b2MakeBox(data.size, data.size);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, box);\n\n return { bodyId: bodyId, shapeId: shapeId, object: box };\n}\n\n/**\n * @typedef {Object} NGonPolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the n-gon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the n-gon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the n-gon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the n-gon.\n * @property {number} [groupIndex] - Collision group index for the n-gon.\n * @property {number} [density] - Density of the n-gon.\n * @property {number} [friction] - Friction of the n-gon.\n * @property {any} [color] - Custom color for the n-gon.\n * @property {number} radius - Radius of the n-gon.\n * @property {number} sides - Number of sides for the n-gon.\n */\n\n/**\n * Creates a regular n-gon polygon and attaches it to a body.\n * @param {NGonPolygonConfig} data - Configuration for the n-gon polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created n-gon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreateNGonPolygon (data)\n{\n if (data.sides < 3 || data.sides > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.sides}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const vertices = [];\n const angleStep = (2 * Math.PI) / data.sides;\n\n for (let i = 0; i < data.sides; i++)\n {\n const angle = i * angleStep;\n const x = data.radius * Math.cos(angle);\n const y = data.radius * Math.sin(angle);\n vertices.push(new b2Vec2(x, y));\n }\n\n let nGon;\n const hull = b2ComputeHull(vertices, data.sides);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {b2Vec2[]} vertices - List of vertices for the polygon.\n */\n\n/**\n * Creates a polygon and attaches it to a body.\n * @param {PolygonConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygon (data)\n{\n if (data.vertices.length < 3 || data.vertices.length > B2_MAX_POLYGON_VERTICES)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n let bodyId = data.bodyId;\n\n if (!bodyId)\n {\n bodyId = b2CreateBody(data.worldId, bodyDef);\n }\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let nGon;\n const hull = b2ComputeHull(data.vertices, data.vertices.length);\n\n if (data.bodyId != null)\n {\n const oldxf = b2GetBodyTransform(data.worldId, data.bodyId);\n const xf = new b2Transform(data.position, oldxf.q);\n nGon = b2MakeOffsetPolygon(hull, 0, xf);\n }\n else\n {\n nGon = b2MakePolygon(hull, 0);\n }\n\n const shapeId = b2CreatePolygonShape(bodyId, shapeDef, nGon);\n\n return { bodyId: bodyId, shapeId: shapeId, object: nGon };\n}\n\n\n/**\n * @typedef {Object} PolygonVertexConfig\n * @property {b2WorldId} worldId - ID for the world in which to create the polygon.\n * @property {b2BodyDef} [bodyDef] - Body definition for the polygon.\n * @property {number} [type] - Type of the body (static, dynamic, kinematic).\n * @property {b2Vec2} [position] - Position of the polygon's center.\n * @property {b2BodyId} [bodyId] - Existing body ID if adding as a fixture.\n * @property {b2ShapeDef} [shapeDef] - Shape definition for the polygon.\n * @property {number} [groupIndex] - Collision group index for the polygon.\n * @property {number} [density] - Density of the polygon.\n * @property {number} [friction] - Friction of the polygon.\n * @property {number} [restitution=0.1] - Restitution of the polygon.\n * @property {any} [color] - Custom color for the polygon.\n * @property {number[]} indices - List of indices to the vertices for the polygon.\n * @property {number[]} vertices - List of vertices for the polygon in number pairs [x0,y0, x1,y1, ... xN,yN].\n * @property {b2Vec2} vertexOffset - Offset to recenter the vertices if they are not zero based.\n * @property {b2Vec2} vertexScale - Scale for the vertices, defaults to 1, 1.\n * @property {string} [url] - URL location of the XML data file, if we're using one.\n * @property {string} [key] - Name 'key' to find the correct data in the XML.\n */\n\n/**\n * Creates a polygon from Earcut CDT data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromEarcut (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n const parts = [];\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert earcut triangle data into point lists suitable for box2D\n for (let i = 0, l = data.indices[ 0 ].length; i < l; i += 3)\n {\n const part = [];\n\n for (let j = 0; j < 3; j++)\n {\n const index = data.indices[ 0 ][ i + j ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n}\n\n/**\n * Creates a polygon from Vertex and Index data and attaches it to a body.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePolygonFromVertices (data)\n{\n if (data.vertices.length < 3)\n {\n console.warn(`WARNING: invalid number of sides for a polygon (${data.vertices.length}).`);\n\n return null;\n }\n\n const bodyDef = data.bodyDef || b2DefaultBodyDef();\n setIfDef(bodyDef, \"type\", data.type);\n setIfDef(bodyDef, \"position\", data.position);\n\n const shapeDef = data.shapeDef || b2DefaultShapeDef();\n setIfDef(shapeDef, \"density\", data.density);\n setIfDef(shapeDef, \"friction\", data.friction);\n setIfDef(shapeDef, \"restitution\", data.restitution);\n setIfDef(shapeDef.filter, \"groupIndex\", data.groupIndex);\n setIfDef(shapeDef, \"customColor\", data.color);\n\n let scale = data.vertexScale;\n\n if (!scale) { scale = new b2Vec2(1, 1); }\n let offset = data.vertexOffset;\n\n if (!offset) { offset = new b2Vec2(0, 0); }\n\n // convert indexed vertex data into point lists suitable for box2D\n const parts = [];\n\n for (let i = 0, l = data.indices.length; i < l; i++)\n {\n const part = [];\n const indices = data.indices[ i ];\n\n for (let p = 0, pl = indices.length; p < pl; p++)\n {\n const index = indices[ p ] * 2;\n part.push(new b2Vec2((data.vertices[ index ] + offset.x) * scale.x, (data.vertices[ index + 1 ] + offset.y) * scale.y));\n }\n parts.push(part);\n }\n\n // create a Shape for each point list\n let body = null;\n parts.forEach(part =>\n {\n if (!body)\n {\n // create a Body for the entire object using the first point list\n body = CreatePolygon({\n worldId: data.worldId,\n type: b2BodyType.b2_dynamicBody,\n bodyDef: bodyDef,\n\n // position: position,\n vertices: part,\n density: 1.0,\n friction: 0.3,\n color: b2HexColor.b2_colorSkyBlue\n });\n }\n else\n {\n // create a Shape attached to that body for all remaining point lists\n const hull = b2ComputeHull(part, part.length);\n const nGon = b2MakePolygon(hull, 0);\n b2CreatePolygonShape(body.bodyId, shapeDef, nGon);\n }\n });\n\n return body;\n}\n\n\n/**\n * Creates a polygon from PhysicsEditor XML data and attaches it to a body.\n * It is recommended to prepare data with this _before_ the game loop starts; It is async and quite slow.\n * @param {PolygonVertexConfig} data - Configuration for the polygon.\n * @returns {Promise<{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}>} The created polygon's body ID, shape ID, and object.\n * @memberof Physics\n */\nexport function CreatePhysicsEditorShape (data)\n{\n const key = data.key;\n const url = data.url;\n\n async function loadXMLFromFile (url)\n {\n try\n {\n const response = await fetch(url);\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n\n return xmlDoc;\n }\n catch (error)\n {\n console.error(\"Error loading XML:\", error);\n\n throw error;\n }\n }\n\n function extractPolygons (key, xmlDoc)\n {\n const polygonElements = xmlDoc.querySelectorAll(`body[name=${key}] fixtures polygon`);\n\n const uniqueVertices = [];\n const polygonIndices = [];\n\n // find or add vertex\n function getVertexIndex (x, y)\n {\n // exists? (with tiny epsilon)\n const epsilon = 0.000001;\n const last = uniqueVertices.length;\n\n for (let i = 0; i < last; i += 2)\n {\n if (Math.abs(uniqueVertices[ i ] - x) < epsilon &&\n Math.abs(uniqueVertices[ i + 1 ] - y) < epsilon)\n {\n return i / 2;\n }\n }\n\n // add new vertex if not\n uniqueVertices.push(x, y);\n\n return last / 2;\n }\n\n // for each polygon from the XML\n Array.from(polygonElements).forEach(polygon =>\n {\n const numbers = polygon.textContent\n .trim()\n .split(/[,\\s]+/) // commas or whitespace\n .map(Number);\n\n // create indices\n const polygonIndexList = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n const vertexIndex = getVertexIndex(numbers[ i ], numbers[ i + 1 ]);\n polygonIndexList.push(vertexIndex);\n }\n polygonIndices.push(polygonIndexList);\n });\n\n return {\n vertices: uniqueVertices, // a flat array of x,y coordinates\n indices: polygonIndices // an array of index arrays, one per polygon\n };\n }\n\n function createPolygons (polygons)\n {\n // create a polygon body from the vertex list and index list-of-lists\n // merge the provided data object defining the body with the data we've extracted from XML\n return CreatePolygonFromVertices({\n ...data,\n indices: polygons.indices,\n vertices: polygons.vertices\n });\n }\n\n return new Promise(async (resolve, reject) =>\n {\n try\n {\n const xmlDoc = await loadXMLFromFile(url);\n const polygons = extractPolygons(key, xmlDoc);\n const result = createPolygons(polygons);\n resolve(result);\n }\n catch (error)\n {\n console.error(\"Error:\", error);\n reject(error);\n }\n });\n}\n\n\n/**\n * @typedef {Object} RevoluteJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2RevoluteJointDef} [jointDef] - A pre-existing b2RevoluteJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [lowerAngle] - Lower limit of the joint's angle.\n * @property {number} [upperAngle] - Upper limit of the joint's angle.\n * @property {boolean} [enableLimit] - Whether to enable angle limits.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * @property {number} [drawSize] - The size to use when drawing the joint.\n */\n\n/**\n * Creates a revolute joint between two bodies.\n * @param {RevoluteJointConfig} data - Configuration for the revolute joint.\n * @returns {{jointId: b2JointId}} The ID of the created revolute joint.\n * @memberof Physics\n */\nexport function CreateRevoluteJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2RevoluteJointDef();\n }\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"lowerAngle\", data.lowerAngle);\n setIfDef(jointDef, \"upperAngle\", data.upperAngle);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n setIfDef(jointDef, \"drawSize\", data.drawSize);\n\n const jointId = b2CreateRevoluteJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WeldJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WeldJointDef} [jointDef] - A pre-existing b2WeldJointDef.\n * @property {b2BodyId} bodyIdA - The first body to weld with this joint.\n * @property {b2BodyId} bodyIdB - The second body to weld with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [hertz] - The frequency at which the weld joint is enforced.\n * @property {number} [dampingRatio] - The angular damping ratio when the weld joint is springing back into alignment.\n * @property {number} [referenceAngle] - Reference angle for the weld joint at rest.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a weld joint between two bodies.\n * @param {WeldJointConfig} data - Configuration for the weld joint.\n * @returns {{jointId: b2JointId}} The ID of the created weld joint.\n * @memberof Physics\n */\nexport function CreateWeldJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WeldJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n const rotA = b2Body_GetRotation(data.bodyIdA);\n const rotB = b2Body_GetRotation(data.bodyIdB);\n jointDef.referenceAngle = b2RelativeAngle(rotB, rotA);\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"angularHertz\", data.hertz);\n setIfDef(jointDef, \"angularDampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWeldJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} DistanceJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2DistanceJointDef} [jointDef] - A pre-existing b2DistanceJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {number} [length] - The natural length of the joint.\n * @property {number} [minLength] - The minimum allowed length of the joint.\n * @property {number} [maxLength] - The maximum allowed length of the joint.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable length limits.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a distance joint between two bodies.\n * @param {DistanceJointConfig} data - Configuration for the distance joint.\n * @returns {{jointId: b2JointId}} The ID of the created distance joint.\n * @memberof Physics\n */\nexport function CreateDistanceJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2DistanceJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"length\", data.length);\n setIfDef(jointDef, \"minLength\", data.minLength);\n setIfDef(jointDef, \"maxLength\", data.maxLength);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateDistanceJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} WheelJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2WheelJointDef} [jointDef] - A pre-existing b2WheelJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorTorque] - The maximum torque the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a wheel joint between two bodies.\n * @param {WheelJointConfig} data - Configuration for the wheel joint.\n * @returns {{jointId: b2JointId}} The ID of the created wheel joint.\n * @memberof Physics\n */\nexport function CreateWheelJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2WheelJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorTorque\", data.maxMotorTorque);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateWheelJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} PrismaticJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2PrismaticJointDef} [jointDef] - A pre-existing b2PrismaticJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [anchorA] - Local position of the anchor point on the first body.\n * @property {b2Vec2} [anchorB] - Local position of the anchor point on the second body.\n * @property {b2Vec2} [axis] - The local axis for the joint movement on body A.\n * @property {number} [referenceAngle] - The reference angle between the bodies.\n * @property {boolean} [enableSpring] - Whether to enable the joint's spring.\n * @property {number} [hertz] - The frequency of the joint's spring.\n * @property {number} [dampingRatio] - The damping ratio of the joint's spring.\n * @property {boolean} [enableLimit] - Whether to enable translation limits.\n * @property {number} [lowerTranslation] - The lower translation limit.\n * @property {number} [upperTranslation] - The upper translation limit.\n * @property {boolean} [enableMotor] - Whether to enable the joint's motor.\n * @property {number} [maxMotorForce] - The maximum force the motor can apply.\n * @property {number} [motorSpeed] - The desired motor speed.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n/**\n * Creates a prismatic joint between two bodies.\n * @param {PrismaticJointConfig} data - Configuration for the prismatic joint.\n * @returns {{jointId: b2JointId}} The ID of the created prismatic joint.\n * @memberof Physics\n */\nexport function CreatePrismaticJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2PrismaticJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n setIfDef(jointDef, \"localAnchorA\", data.anchorA);\n setIfDef(jointDef, \"localAnchorB\", data.anchorB);\n setIfDef(jointDef, \"localAxisA\", data.axis);\n\n setIfDef(jointDef, \"referenceAngle\", data.referenceAngle);\n\n setIfDef(jointDef, \"enableSpring\", data.enableSpring);\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n\n setIfDef(jointDef, \"enableLimit\", data.enableLimit);\n setIfDef(jointDef, \"lowerTranslation\", data.lowerTranslation);\n setIfDef(jointDef, \"upperTranslation\", data.upperTranslation);\n\n setIfDef(jointDef, \"enableMotor\", data.enableMotor);\n setIfDef(jointDef, \"maxMotorForce\", data.maxMotorForce);\n setIfDef(jointDef, \"motorSpeed\", data.motorSpeed);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreatePrismaticJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n\n/**\n * @typedef {Object} MotorJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MotorJointDef} [jointDef] - A pre-existing b2MotorJointDef.\n * @property {b2BodyId} bodyIdA - The first body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second body to connect with this joint.\n * @property {b2Vec2} [linearOffset] - The desired linear offset in frame A.\n * @property {number} [maxForce] - The maximum force that can be applied to reach the target offsets.\n * @property {number} [angularOffset] - The desired angular offset.\n * @property {number} [maxTorque] - The maximum torque that can be applied to reach the target angular offset.\n * @property {number} [correctionFactor] - Position correction factor in the range [0,1].\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n */\n\n// NOTES about Motor Joints\n// when 'correctionFactor' == 0.0 the body will not move\n// if linking to the ground, 'bodyA' should be the ground body or the motion will be wrong\n// 'linearOffset' is the world destination, not an offset from the starting position\n\n/**\n * Creates a motor joint between two bodies.\n * @param {MotorJointConfig} data - Configuration for the motor joint.\n * @returns {{jointId: b2JointId}} The ID of the created motor joint.\n * @memberof Physics\n */\nexport function CreateMotorJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MotorJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"linearOffset\", data.linearOffset);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n setIfDef(jointDef, \"angularOffset\", data.angularOffset);\n setIfDef(jointDef, \"maxTorque\", data.maxTorque);\n setIfDef(jointDef, \"correctionFactor\", data.correctionFactor);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMotorJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n\n/**\n * @typedef {Object} MouseJointConfig\n * @property {b2WorldId} worldId - ID for the world in which the bodies and joint exist.\n * @property {b2MouseJointDef} [jointDef] - A pre-existing b2MouseJointDef.\n * @property {b2BodyId} bodyIdA - The first (usually static) body to connect with this joint.\n * @property {b2BodyId} bodyIdB - The second (usually dynamic) body to connect with this joint.\n * @property {b2Vec2} [target] - The initial world target point.\n * @property {number} [hertz] - The response frequency.\n * @property {number} [dampingRatio] - The damping ratio.\n * @property {number} [maxForce] - The maximum force that can be exerted to reach the target point.\n * @property {boolean} [collideConnected] - Whether the connected bodies should collide.\n * e.g. worldId:worldId, bodyIdA:mouseCircle.bodyId, bodyIdB:mouseBox.bodyId, target:new b2Vec2(0, 0), hertz:30.0, dampingRatio:0.999, maxForce:35000\n */\n\n/**\n * Creates a mouse joint between two bodies.\n * @param {MouseJointConfig} data - Configuration for the mouse joint.\n * @returns {{jointId: b2JointId}} The ID of the created mouse joint.\n * @memberof Physics\n */\nexport function CreateMouseJoint (data)\n{\n console.assert(data.worldId != undefined);\n console.assert(data.bodyIdA != undefined && data.bodyIdB != undefined);\n\n let jointDef = data.jointDef;\n\n if (!jointDef)\n {\n jointDef = new b2MouseJointDef();\n }\n\n jointDef.bodyIdA = data.bodyIdA;\n jointDef.bodyIdB = data.bodyIdB;\n\n setIfDef(jointDef, \"target\", data.target); // transferred to b2MouseJoint.targetA\n setIfDef(jointDef, \"hertz\", data.hertz);\n setIfDef(jointDef, \"dampingRatio\", data.dampingRatio);\n setIfDef(jointDef, \"maxForce\", data.maxForce);\n\n setIfDef(jointDef, \"collideConnected\", data.collideConnected);\n\n const jointId = b2CreateMouseJoint(data.worldId, jointDef);\n\n return { jointId: jointId };\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2AABB, b2Add, b2Sub, b2TransformPointOut, b2Vec2 } from './include/math_functions_h.js';\nimport { b2BodyId, b2WorldId } from './main.js';\n\nimport { b2Body_GetShapes } from './body_c.js';\nimport { b2ComputeShapeAABB } from './shape_c.js';\nimport { b2DebugDraw } from './include/types_h.js';\nimport { b2GetWorldFromId } from './world_c.js';\n\n/**\n * @namespace DebugDraw\n */\n\nconst p0 = new b2Vec2();\nconst disableDrawing = false;\n\n/**\n * @function CreateDebugDraw\n * @description Creates a debug drawing interface for Box2D that renders shapes to a canvas context. \n * The canvas is automatically sized to 1280x720 or 720x1280 based on window orientation. \n * All coordinates are transformed from Box2D world space to screen space. \n * This feature isn't meant for production. It is purely for debugging and testing. The code\n * is not optimized, stable or extensible. Implement your own drawing code for production.\n * @param {HTMLCanvasElement} canvas - The canvas element to draw on\n * @param {CanvasRenderingContext2D} ctx - The 2D rendering context for the canvas\n * @param {number} [scale=20] - The scale factor to convert Box2D coordinates to pixels\n * @returns {b2DebugDraw} A debug draw instance with methods for rendering Box2D shapes\n * The debug draw instance includes methods for drawing:\n * - Polygons (outlined and filled)\n * - Circles (outlined and filled)\n * - Capsules (outlined and filled)\n * - Images mapped to shapes\n * - Line segments\n * - Points\n * - Transforms\n */\nexport function CreateDebugDraw(canvas, ctx, scale = 20.0)\n{\n let wide = 1280;\n let high = 720;\n\n if (canvas) {\n\n function resizeCanvas() {\n \n if (window.innerWidth < window.innerHeight) {\n // portrait mode\n wide = canvas.width = 720;\n high = canvas.height = 1280;\n } else {\n // landscape mode\n wide = canvas.width = 1280;\n high = canvas.height = 720;\n }\n\n const dpi = window.devicePixelRatio;\n\n canvas.width = wide * dpi;\n canvas.height = high * dpi;\n \n canvas.style.width = wide + 'px';\n canvas.style.height = high + 'px';\n \n ctx.scale(dpi, dpi);\n }\n\n window.addEventListener('resize', resizeCanvas);\n\n resizeCanvas();\n }\n\n const draw = new b2DebugDraw();\n\n if (disableDrawing) {\n draw.DrawCircle = () => { return; }\n draw.DrawPoint = () => { return; }\n draw.DrawPolygon = () => { return; }\n draw.DrawImageCapsule = () => { return; }\n draw.DrawImageCircle = () => { return; }\n draw.DrawImagePolygon = () => { return; }\n draw.DrawSegment = () => { return; }\n draw.DrawSolidCapsule = () => { return; }\n draw.DrawSolidCircle = () => { return; }\n draw.DrawSolidPolygon = () => { return; }\n draw.DrawString = () => { return; }\n draw.DrawTransform = () => { return; }\n return draw;\n }\n\n draw.DrawPolygon = function(xf, vs, ps, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n };\n\n draw.DrawImagePolygon = function(xf, shape, ctx) {\n let aabb = b2ComputeShapeAABB(shape, xf);\n\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n const centerX = xf.p.x;\n const centerY = xf.p.y;\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY - cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // Negate the angle because we're rotating the context, not the object\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n let drawWidth = aabb.upperBoundX - aabb.lowerBoundX;\n let drawHeight = aabb.upperBoundY - aabb.lowerBoundY;\n const aspectRatio = drawWidth / drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight *= scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth *= scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight\n );\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidPolygon = function(xf, vs, ps, rad, col, ctx) {\n ctx.beginPath();\n \n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; //((col >> 24) & 0xFF) / 255;\n \n //const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the polygon\n for (let i = 0; i < ps; i++) {\n b2TransformPointOut( xf, vs[i], p0 );\n p0.y = -p0.y;\n //let p1 = b2MulSV(scale, p0);\n let p1X = scale * p0.x;\n let p1Y = scale * p0.y;\n //let v = b2Add(p1, c);\n let vX = p1X + cX;\n let vY = p1Y + cY;\n \n if (i === 0) {\n ctx.moveTo(vX, vY);\n } else {\n ctx.lineTo(vX, vY);\n }\n }\n \n ctx.closePath();\n \n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = rad * 2; // Use the radius for line width\n ctx.stroke();\n };\n\n draw.DrawCircle = function(center, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n // Transform the center point\n //let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * cX;\n const scaleCenterY = scale * cY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCircle = function(xf, rad, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n transformedCenterY = -transformedCenterY;\n \n // Save the current canvas state\n ctx.save();\n \n // Move to the center of where we want to draw the image\n ctx.translate(transformedCenterX, transformedCenterY);\n \n // Rotate the canvas\n // The rotation is counter-clockwise in Box2D, but clockwise in canvas\n // So we need to negate the angle\n const angle = -Math.atan2(xf.q.s, xf.q.c);\n ctx.rotate(angle);\n \n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n let drawWidth, drawHeight;\n \n if (aspectRatio > 1) {\n drawHeight = rad * 2 * scale * imageScale.x;\n drawWidth = drawHeight * aspectRatio * imageScale.y;\n } else {\n drawWidth = rad * 2 * scale * imageScale.x;\n drawHeight = drawWidth / aspectRatio * imageScale.y;\n }\n \n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image, -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y, drawWidth, drawHeight);\n \n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCircle = function(xf, rad, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the center point\n //let center = b2TransformPoint(xf, new b2Vec2(0, 0));\n const centerX = xf.p.x;\n const centerY = -xf.p.y;\n // let scaledCenter = b2MulSV(scale, center);\n const scaleCenterX = scale * centerX;\n const scaleCenterY = scale * centerY;\n //let transformedCenter = b2Add(scaledCenter, c);\n let transformedCenterX = scaleCenterX + cX;\n let transformedCenterY = scaleCenterY + cY;\n \n // Draw the circle\n ctx.arc(transformedCenterX, transformedCenterY, rad * scale, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2; // Use a fixed line width for the circle outline\n ctx.stroke();\n };\n\n draw.DrawImageCapsule = function(p1, p2, radius, shape, ctx) {\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n\n const rs = radius * scale;\n\n // Transform the points\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Save the current canvas state\n ctx.save();\n \n ctx.translate(transformedP1X + dx / 2, transformedP1Y + dy / 2);\n ctx.rotate(angle + Math.PI / 2);\n\n // Calculate positioning to center the image\n const image = shape.image;\n const imageScale = shape.imageScale || new b2Vec2(1, 1);\n const imageOffset = shape.imageOffset || new b2Vec2(0, 0);\n const aspectRatio = image.width / image.height;\n const overlap = 1.1;\n let drawHeight = (length + rs * 2) * overlap * imageScale.y;\n let drawWidth = (rs * 2) * overlap * Math.abs(imageScale.x);\n \n // negative imageScale.x indicates the image should be mirrored\n ctx.scale(Math.sign(imageScale.x), 1);\n\n // Draw the image centered at (0, 0) of the rotated context\n ctx.drawImage(image,\n shape.imageRect.lowerBoundX, shape.imageRect.lowerBoundY,\n shape.imageRect.upperBoundX, shape.imageRect.upperBoundY,\n -drawWidth / 2 + drawWidth * imageOffset.x, -drawHeight / 2 + drawHeight * imageOffset.y,\n drawWidth, drawHeight);\n\n // Restore the canvas state\n ctx.restore();\n };\n\n draw.DrawSolidCapsule = function(p1, p2, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // ((col >> 24) & 0xFF) / 255;\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the points\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n //let scaledP1 = b2MulSV(scale, tp1);\n const scaledP1X = scale * tp1.x;\n const scaledP1Y = scale * tp1.y;\n //let scaledP2 = b2MulSV(scale, tp2);\n const scaledP2X = scale * tp2.x;\n const scaledP2Y = scale * tp2.y;\n // let transformedP1 = b2Add(scaledP1, c);\n let transformedP1X = scaledP1X + cX;\n let transformedP1Y = scaledP1Y + cY;\n // let transformedP2 = b2Add(scaledP2, c);\n let transformedP2X = scaledP2X + cX;\n let transformedP2Y = scaledP2Y + cY;\n \n // Calculate the angle and length of the capsule's main axis\n let dx = transformedP2X - transformedP1X;\n let dy = transformedP2Y - transformedP1Y;\n let angle = Math.atan2(dy, dx);\n let length = Math.sqrt(dx * dx + dy * dy);\n \n // Draw the capsule\n ctx.save();\n ctx.translate(transformedP1X, transformedP1Y);\n ctx.rotate(angle);\n \n ctx.beginPath();\n \n // Draw the capsule shape\n ctx.arc(0, 0, radius * scale, Math.PI / 2, -Math.PI / 2);\n ctx.lineTo(length, -radius * scale);\n ctx.arc(length, 0, radius * scale, -Math.PI / 2, Math.PI / 2);\n ctx.lineTo(0, radius * scale);\n ctx.closePath();\n \n // Fill the capsule\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Stroke the capsule (who's a good capsule? You are, yes you are!)\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 2;\n ctx.stroke();\n \n ctx.restore();\n };\n\n draw.DrawSegment = function(p1, p2, col, ctx) {\n ctx.beginPath();\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to the polygon function\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform and draw the line\n //let tp1 = b2TransformPoint(b2Transform.identity(), p1);\n //let tp2 = b2TransformPoint(b2Transform.identity(), p2);\n const tp1 = p1;\n const tp2 = p2;\n \n tp1.y = -tp1.y;\n tp2.y = -tp2.y;\n \n //let v1 = b2Add(b2MulSV(scale, tp1), c);\n const v1X = (scale * tp1.x) + cX;\n const v1Y = (scale * tp1.y) + cY;\n //let v2 = b2Add(b2MulSV(scale, tp2), c);\n const v2X = (scale * tp2.x) + cX;\n const v2Y = (scale * tp2.y) + cY;\n \n ctx.moveTo(v1X, v1Y);\n ctx.lineTo(v2X, v2Y);\n \n ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.lineWidth = 2; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.DrawPoint = function(x, y, radius, col, ctx) {\n const r = (col >> 16) & 0xFF;\n const g = (col >> 8) & 0xFF;\n const b = col & 0xFF;\n const a = 0.5; // Fixed alpha value, similar to previous functions\n // const c = new b2Vec2(wide / 2, high / 2);\n const cX = (wide >> 1) + this.positionOffset.x;\n const cY = (high >> 1) + this.positionOffset.y;\n \n // Transform the point (PJB: except it's the identity, it does do anything)\n //b2TransformPoint(b2Transform.identity(), p);\n // let tp = new b2Vec2(x, y);\n // tp.y = -tp.y;\n y = -y;\n\n //let v = b2Add(b2MulSV(scale, tp), c);\n const vX = (scale * x) + cX;\n const vY = (scale * y) + cY;\n \n // Draw the point as a circle\n ctx.beginPath();\n ctx.arc(vX, vY, radius, 0, 2 * Math.PI);\n ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;\n ctx.fill();\n \n // Add a stroke to the circle\n ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;\n ctx.lineWidth = 1; // You can adjust this value as needed\n ctx.stroke();\n };\n\n draw.SetPosition = function(x, y) {\n // use half width and height to make the virtual 'camera' look at (x, y)\n draw.positionOffset.x = wide / 2 - x;\n draw.positionOffset.y = y - high / 2;\n }\n\n draw.context = ctx;\n \n return draw;\n}\n\n/**\n * @function RAF\n * @summary Implements a requestAnimationFrame loop with timing and FPS tracking\n * @param {function} callback - Function to call each frame with signature (deltaTime, totalTime, currentFps)\n * @param {number} callback.deltaTime - Time elapsed since last frame in seconds, capped at 0.1s\n * @param {number} callback.totalTime - Total accumulated time in seconds\n * @param {number} callback.currentFps - Current frames per second, updated once per second\n * @description\n * Creates an animation loop using requestAnimationFrame that tracks timing information\n * and FPS. The callback is invoked each frame with the time delta, total time, and\n * current FPS. Frame delta time is capped at 100ms to avoid large time steps.\n */\nexport function RAF(callback)\n{\n let lastTime = 0;\n let totalTime = 0;\n\n let frameCount = 0;\n let lastFpsUpdateTime = 0;\n let currentFps = 0;\n\n function update(currentTime)\n {\n requestAnimationFrame(update);\n\n if (lastTime === 0) {\n lastTime = currentTime;\n }\n const deltaTime = Math.min((currentTime - lastTime) / 1000, 1 / 10);\n lastTime = currentTime;\n totalTime += deltaTime;\n\n callback(deltaTime, totalTime, currentFps);\n\n frameCount++;\n if (currentTime - lastFpsUpdateTime >= 1000) {\n currentFps = Math.round((frameCount * 1000) / (currentTime - lastFpsUpdateTime));\n frameCount = 0;\n lastFpsUpdateTime = currentTime;\n }\n }\n\n requestAnimationFrame(update);\n}\n\n/**\n *\n * IMAGE HELPERS\n * \n */\nfunction loadPNGImage(imageUrl)\n{\n return new Promise((resolve, reject) =>\n {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (event) =>\n {\n const errorDetails = {\n message: 'Failed to load image',\n url: imageUrl,\n event: event\n };\n reject(new Error(JSON.stringify(errorDetails, null, 2)));\n };\n img.src = imageUrl;\n });\n}\n\n/**\n * Attach a graphic image to a physics body\n * @function AttachImage\n * @param {number} worldId - The ID of the Box2D world\n * @param {number} bodyId - The ID of the body to attach the image to\n * @param {string} path - Directory path where the image is located\n * @param {string} imgName - Name of the image file\n * @param {b2Vec2} [drawOffset=null] - Offset vector for drawing the image\n * @param {b2Vec2} [drawScale=null] - Scale vector for drawing the image\n * @param {b2Vec2} [sourcePosition=null] - Position in the source image to start drawing from\n * @param {b2Vec2} [sourceSize=null] - Size of the region to draw from the source image\n * @returns {Object} The modified shape object with attached image properties\n * @description\n * Attaches an image to the last shape of a Box2D body. The function loads a PNG image\n * asynchronously and sets up drawing parameters including offset, scale, and source\n * rectangle coordinates. The image is stored in the shape's properties for later rendering.\n */\nexport function AttachImage(worldId, bodyId, path, imgName, drawOffset = null, drawScale = null, sourcePosition = null, sourceSize = null)\n{\n const world = b2GetWorldFromId(worldId);\n const shapes = [];\n b2Body_GetShapes(bodyId, shapes);\n const shape = world.shapeArray[shapes[shapes.length - 1].index1 - 1];\n shape.imageOffset = drawOffset;\n shape.imageScale = drawScale;\n shape.imageRect = new b2AABB(sourcePosition.x, sourcePosition.y, sourceSize.x, sourceSize.y);\n // assume images are in 'images' folder and one level up\n const fullPath = path + \"/\" + imgName;\n loadPNGImage(fullPath)\n .then((loadedImage) =>\n {\n shape.image = loadedImage;\n })\n .catch((error) =>\n {\n console.error('Error loading local image:', error);\n });\n return shape;\n}\n\n/**\n * \n * UI HELPERS\n * \n */\nfunction getMousePosUV(canvas, ps)\n{\n const rect = canvas.getBoundingClientRect();\n\n return {\n u: (ps.x - rect.left) / rect.width,\n v: 1.0 - (ps.y - rect.top) / rect.height\n };\n}\n\n/**\n * @function ConvertScreenToWorld\n * @description\n * Converts screen/canvas coordinates to world space coordinates in the Box2D physics system.\n * @param {HTMLCanvasElement} canvas - The canvas element being used for rendering\n * @param {number} drawScale - The scale factor between screen and world coordinates\n * @param {Object} ps - The screen position coordinates\n * @returns {b2Vec2} A vector containing the world space coordinates\n * @example\n * // Convert mouse click position to world coordinates\n * const worldPos = ConvertScreenToWorld(myCanvas, 30, mousePos);\n */\nexport function ConvertScreenToWorld(canvas, drawScale, ps)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n let uv = getMousePosUV(canvas, ps);\n var ratio = w / h;\n var center = new b2Vec2(0, 0); // could be scroll position if there's a camera\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n\n // convert u,v to world point\n var pw = new b2Vec2((1 - uv.u) * lower.x + uv.u * upper.x, (1 - uv.v) * lower.y + uv.v * upper.y);\n return pw;\n}\n\n/**\n * @function ConvertWorldToScreen\n * @summary Converts world coordinates to screen (canvas) coordinates\n * @param {HTMLCanvasElement} canvas - The canvas element used for rendering\n * @param {number} drawScale - The scale factor for converting world units to pixels\n * @param {b2Vec2} pw - The world position to convert\n * @returns {b2Vec2} The converted screen coordinates as a b2Vec2\n * @description\n * Transforms a position from world space to screen space, taking into account\n * the canvas dimensions, aspect ratio, and zoom level. The function maps the\n * world coordinates to normalized coordinates (0-1) and then scales them to\n * screen pixels.\n */\nexport function ConvertWorldToScreen(canvas, drawScale, pw)\n{\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n \n var ratio = w / h;\n var center = new b2Vec2(0, 0);\n var zoom = (h / 2) / drawScale;\n\n // calculate the screen extents\n var extents = new b2Vec2(zoom * ratio, zoom);\n var lower = b2Sub(center, extents);\n var upper = b2Add(center, extents);\n \n // convert world point to u,v coordinates\n var u = (pw.x - lower.x) / (upper.x - lower.x);\n var v = (pw.y - lower.y) / (upper.y - lower.y);\n \n // convert u,v to screen coordinates\n var ps = new b2Vec2(u * w, v * h);\n return ps;\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2Add, b2Vec2 } from \"./include/math_functions_h.js\";\nimport { b2BodyType, b2RevoluteJointDef } from \"./include/types_h.js\";\nimport { b2Body_GetLocalPoint, b2Body_SetUserData, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateRevoluteJoint, b2DestroyJoint } from \"./include/joint_h.js\";\n\nimport { B2_NULL_INDEX } from \"./include/core_h.js\";\nimport { CreateCapsule } from \"./physics.js\";\nimport { b2Capsule } from \"./include/collision_h.js\";\nimport { b2CreateCapsuleShape } from \"./include/shape_h.js\";\nimport { b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2JointId } from \"./include/id_h.js\";\n\n/**\n * @namespace Ragdoll\n */\n\nclass JointedBone\n{\n constructor()\n {\n this.bodyId = null;\n this.jointId = null;\n this.frictionScale = 1.0;\n this.parentIndex = -1;\n this.name = \"\";\n }\n}\n\nexport class Skeletons\n{\n static HumanBones =\n {\n e_hip: 0,\n e_torso: 1,\n e_head: 2,\n e_upperLeftLeg: 3,\n e_lowerLeftLeg: 4,\n e_upperRightLeg: 5,\n e_lowerRightLeg: 6,\n e_upperLeftArm: 7,\n e_lowerLeftArm: 8,\n e_upperRightArm: 9,\n e_lowerRightArm: 10,\n e_count: 11\n };\n\n static sideViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ 0, -0.02 ], center2: [ 0, 0.02 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0, 1.225 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0, 0.975 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.25 * Math.PI, 0 ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0, 0.9 ], limits: [ -0.05 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0, 0.625 ], limits: [ -0.5 * Math.PI, -0.02 * Math.PI ] },\n { boneName: 'upperLeftArm', pivot: [ 0, 1.35 ], limits: [ -0.1 * Math.PI, 0.8 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0, 1.35 ], limits: null },\n { boneName: 'lowerRightArm', pivot: [ 0, 1.1 ], limits: [ 0.01 * Math.PI, 0.5 * Math.PI ] },\n ]\n };\n\n static frontViewHuman11 =\n {\n BONE_DATA: [\n { name: 'hip', parentIndex: -1, position: [ 0, 0.95 ], capsule: { center1: [ -0.03, 0 ], center2: [ 0.03, 0 ], radius: 0.095 } },\n { name: 'torso', parentIndex: 0, position: [ 0, 1.2 ], capsule: { center1: [ 0, -0.135 ], center2: [ 0, 0.135 ], radius: 0.09 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 1, position: [ 0, 1.5 ], capsule: { center1: [ 0, -0.0325 ], center2: [ 0, 0.0325 ], radius: 0.08 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'upperLeftLeg', parentIndex: 0, position: [ -0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerLeftLeg', parentIndex: 3, position: [ -0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"left\" },\n { name: 'upperRightLeg', parentIndex: 0, position: [ 0.1, 0.775 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.06 } },\n { name: 'lowerRightLeg', parentIndex: 5, position: [ 0.1, 0.475 ], capsule: { center1: [ 0, -0.14 ], center2: [ 0, 0.125 ], radius: 0.05 }, frictionScale: 0.5, foot: \"right\" },\n { name: 'upperLeftArm', parentIndex: 1, position: [ -0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerLeftArm', parentIndex: 7, position: [ -0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperRightArm', parentIndex: 1, position: [ 0.15, 1.22 ], capsule: { center1: [ 0, -0.125 ], center2: [ -0.05, 0.125 ], radius: 0.035 }, frictionScale: 0.5 },\n { name: 'lowerRightArm', parentIndex: 9, position: [ 0.15, 0.97 ], capsule: { center1: [ 0, -0.125 ], center2: [ 0, 0.125 ], radius: 0.03 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'torso', pivot: [ 0, 1.0 ], limits: [ -0.1 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'head', pivot: [ 0, 1.4 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'upperLeftLeg', pivot: [ -0.1, 0.9 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftLeg', pivot: [ -0.1, 0.625 ], limits: [ 0, 0.5 * Math.PI ] },\n { boneName: 'upperRightLeg', pivot: [ 0.1, 0.9 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'lowerRightLeg', pivot: [ 0.1, 0.625 ], limits: [ -0.5 * Math.PI, 0 ] },\n { boneName: 'upperLeftArm', pivot: [ -0.12, 1.35 ], limits: [ -0.7 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'lowerLeftArm', pivot: [ -0.16, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n { boneName: 'upperRightArm', pivot: [ 0.12, 1.35 ], limits: [ -0.1 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'lowerRightArm', pivot: [ 0.14, 1.10 ], limits: [ 0, 0.75 * Math.PI ] },\n ]\n };\n\n static ElephantBones =\n {\n e_torso: 0,\n e_head: 1,\n e_trunkBase: 2,\n e_trunkMid: 3,\n e_trunkTip: 4,\n e_upperFrontLegL: 5,\n e_lowerFrontLegL: 6,\n e_upperRearLegL: 7,\n e_lowerRearLegL: 8,\n e_tail: 9,\n e_ear: 10,\n e_count: 11,\n };\n\n static sideViewElephant = {\n BONE_DATA: [\n { name: 'torso', parentIndex: -1, position: [ 0, 1.5 ], capsule: { center1: [ 0.8, 0 ], center2: [ -0.8, 0 ], radius: 0.6 }, frictionScale: 0.5 },\n { name: 'head', parentIndex: 0, position: [ -1.4, 2.2 ], capsule: { center1: [ 0.3, 0 ], center2: [ -0.3, 0 ], radius: 0.35 }, frictionScale: 0.25, linearDamping: 0.1 },\n { name: 'trunkBase', parentIndex: 1, position: [ -1.95, 1.85 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.15 } },\n { name: 'trunkMid', parentIndex: 2, position: [ -1.95, 1.4 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.12 } },\n { name: 'trunkTip', parentIndex: 3, position: [ -1.95, 1.05 ], capsule: { center1: [ 0, -0.2 ], center2: [ 0, 0.2 ], radius: 0.08 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'upperFrontLeg', parentIndex: 0, position: [ -0.6, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 } },\n { name: 'lowerFrontLeg', parentIndex: 5, position: [ -0.6, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.18 }, frictionScale: 0.5 },\n { name: 'upperBackLeg', parentIndex: 0, position: [ 0.7, 0.8 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.22 } },\n { name: 'lowerBackLeg', parentIndex: 7, position: [ 0.7, 0.2 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.2 }, frictionScale: 0.5 },\n { name: 'tail', parentIndex: 0, position: [ 1.2, 1.6 ], capsule: { center1: [ 0, -0.3 ], center2: [ 0, 0.3 ], radius: 0.05 }, frictionScale: 0.1, linearDamping: 0.1 },\n { name: 'ear', parentIndex: 1, position: [ -1.1, 2.0 ], capsule: { center1: [ 0, -0.15 ], center2: [ 0, 0.15 ], radius: 0.3 }, frictionScale: 0.1, linearDamping: 0.1 },\n ],\n JOINT_DATA: [\n { boneName: 'head', pivot: [ -1.0, 2.0 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'trunkBase', pivot: [ -1.95, 2 ], limits: [ -0.5 * Math.PI, 0.5 * Math.PI ] },\n { boneName: 'trunkMid', pivot: [ -1.95, 1.55 ], limits: [ -0.7 * Math.PI, 0.7 * Math.PI ] },\n { boneName: 'trunkTip', pivot: [ -1.95, 1.15 ], limits: [ -0.9 * Math.PI, 0.9 * Math.PI ] },\n { boneName: 'upperFrontLeg', pivot: [ -0.6, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerFrontLeg', pivot: [ -0.6, 0.5 ], limits: [ -0.3 * Math.PI, 0.1 * Math.PI ] },\n { boneName: 'upperBackLeg', pivot: [ 0.7, 1.1 ], limits: [ -0.2 * Math.PI, 0.2 * Math.PI ] },\n { boneName: 'lowerBackLeg', pivot: [ 0.7, 0.5 ], limits: [ -0.1 * Math.PI, 0.3 * Math.PI ] },\n { boneName: 'tail', pivot: [ 1.2, 1.9 ], limits: [ -0.4 * Math.PI, 0.4 * Math.PI ] },\n { boneName: 'ear', pivot: [ -1.1, 2.2 ], limits: [ -0.3 * Math.PI, 0.9 * Math.PI ] },\n ]\n };\n}\n\nexport class Ragdoll\n{\n constructor(skeleton, x, y, worldId, groupIndex, color, size = 2)\n {\n this.skeleton = skeleton;\n this.position = new b2Vec2(x, y);\n this.worldId = worldId;\n this.groupIndex = groupIndex;\n this.color = color;\n this.m_scale = size;\n this.frictionTorque = 0.05;\n this.hertz = 0.0;\n this.dampingRatio = 0.5;\n this.jointDrawSize = 0.5;\n this.maxTorque = this.frictionTorque * this.m_scale;\n this.m_bones = [];\n\n this.create();\n }\n\n createBone(boneData)\n {\n const { bodyId } = CreateCapsule({\n worldId: this.worldId,\n position: b2Add(new b2Vec2(boneData.position[0] * this.m_scale, boneData.position[1] * this.m_scale), this.position),\n type: b2BodyType.b2_dynamicBody,\n center1: new b2Vec2(boneData.capsule.center1[0] * this.m_scale, boneData.capsule.center1[1] * this.m_scale),\n center2: new b2Vec2(boneData.capsule.center2[0] * this.m_scale, boneData.capsule.center2[1] * this.m_scale),\n radius: boneData.capsule.radius * this.m_scale,\n density: 1.0,\n friction: 0.2,\n groupIndex: -this.groupIndex,\n color: this.color\n });\n\n const bone = new JointedBone();\n bone.name = boneData.name;\n bone.parentIndex = boneData.parentIndex;\n bone.frictionScale = boneData.frictionScale || 1.0;\n bone.bodyId = bodyId;\n\n if (boneData.foot)\n {\n const footShapeDef = b2DefaultShapeDef();\n footShapeDef.density = 1.0;\n footShapeDef.friction = 0.2;\n footShapeDef.filter.groupIndex = -this.groupIndex;\n footShapeDef.filter.maskBits = 1;\n footShapeDef.customColor = this.color;\n\n const footDir = boneData.foot == \"left\" ? -1 : 1;\n const footCapsule = new b2Capsule();\n footCapsule.center1 = new b2Vec2(footDir * -0.02 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.center2 = new b2Vec2(footDir * 0.13 * this.m_scale, -0.175 * this.m_scale);\n footCapsule.radius = 0.03 * this.m_scale;\n b2CreateCapsuleShape(bodyId, footShapeDef, footCapsule);\n }\n\n return bone;\n }\n\n createJoint(jointData)\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n const parentBone = this.m_bones[bone.parentIndex];\n\n const pivot = b2Add(new b2Vec2(jointData.pivot[0] * this.m_scale, jointData.pivot[1] * this.m_scale), this.position);\n const jointDef = new b2RevoluteJointDef();\n jointDef.bodyIdA = parentBone.bodyId;\n jointDef.bodyIdB = bone.bodyId;\n jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);\n jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);\n \n if (jointData.limits)\n {\n jointDef.enableLimit = true;\n jointDef.lowerAngle = jointData.limits[0];\n jointDef.upperAngle = jointData.limits[1];\n }\n \n jointDef.enableMotor = true;\n jointDef.maxMotorTorque = bone.frictionScale * this.maxTorque;\n jointDef.enableSpring = this.hertz > 0.0;\n jointDef.hertz = this.hertz;\n jointDef.dampingRatio = this.dampingRatio;\n jointDef.drawSize = this.jointDrawSize;\n\n return b2CreateRevoluteJoint(this.worldId, jointDef);\n }\n\n create()\n {\n this.m_bones = this.skeleton.BONE_DATA.map(boneData => this.createBone(boneData));\n\n this.skeleton.JOINT_DATA.forEach(jointData =>\n {\n const bone = this.m_bones.find(b => b.name === jointData.boneName);\n bone.jointId = this.createJoint(jointData);\n });\n\n this.m_bones.forEach(bone => b2Body_SetUserData(bone.bodyId, this));\n\n return this;\n }\n\n destroy()\n {\n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].jointId )\n {\n if ( this.m_bones[i].jointId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyJoint( this.m_bones[i].jointId );\n this.m_bones[i].jointId = new b2JointId();\n }\n }\n }\n \n for ( let i = 0; i < this.m_bones.length; ++i )\n {\n if ( this.m_bones[i].bodyId.index1 - 1 != B2_NULL_INDEX )\n {\n b2DestroyBody( this.m_bones[i].bodyId );\n this.m_bones[i].bodyId = null;\n }\n }\n this.m_bones = null;\n }\n}\n", "/**\n * This file includes code that is:\n * \n * - Copyright 2023 Erin Catto, released under the MIT license.\n * - Copyright 2024 Phaser Studio Inc, released under the MIT license.\n */\n\nimport { b2BodyType, b2DefaultBodyDef, b2DefaultShapeDef } from \"./include/types_h.js\";\nimport { b2Body_ApplyForceToCenter, b2Body_SetUserData, b2CreateBody, b2DestroyBody } from \"./include/body_h.js\";\nimport { b2CreateCircleShape, b2CreatePolygonShape } from \"./include/shape_h.js\";\nimport { b2CreateRevoluteJoint, b2DefaultRevoluteJointDef } from \"./include/joint_h.js\";\n\nimport { b2Circle } from \"./include/collision_h.js\";\nimport { b2MakeBox } from \"./include/geometry_h.js\";\nimport { b2Vec2 } from \"./include/math_functions_h.js\";\n\nfunction approx(value, variation)\n{\n return value + (Math.random() - 0.5) * variation;\n}\n\nexport class ActiveBall\n{\n constructor(id, createdTime)\n {\n this.id = id;\n this.created = createdTime;\n }\n}\n\nfunction shootBall(startPosition, startForce, radius, density, color, worldId)\n{\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_dynamicBody;\n bodyDefBall.fixedRotation = false;\n bodyDefBall.position = startPosition.clone();\n\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = density;\n shapeDefBall.friction = 0.05;\n shapeDefBall.restitution = 0.5;\n shapeDefBall.customColor = color;\n\n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = radius;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n const force = new b2Vec2(approx(startForce.x, 400), approx(startForce.y, 1500));\n b2Body_ApplyForceToCenter(ballId, force, true);\n\n return ballId;\n}\n\nexport class Gun\n{\n constructor(position, power, frequency, life, radius, density, color, worldId)\n {\n this.worldId = worldId;\n this.position = position;\n this.power = power;\n this.frequency = frequency;\n this.life = life;\n this.radius = radius;\n this.density = density;\n this.color = color;\n\n this.activeBalls = [];\n this.nextShotTime = this.frequency;\n this.totalTime = 0;\n }\n\n update(dt)\n {\n if (isNaN(dt)) { return; }\n this.totalTime += dt;\n\n // shoot when it's time\n this.nextShotTime -= dt;\n\n if (this.nextShotTime <= 0)\n {\n this.nextShotTime = Math.max(this.nextShotTime + this.frequency, 1/240);\n const ballId = shootBall(this.position, this.power, this.radius, this.density, this.color, this.worldId);\n const ab = new ActiveBall( ballId, this.totalTime );\n this.activeBalls.push(ab);\n b2Body_SetUserData(ballId, ab);\n }\n\n // kill old balls\n for (let i = this.activeBalls.length - 1; i >= 0; --i)\n {\n const ab = this.activeBalls[i];\n\n if (this.totalTime - ab.created >= this.life)\n {\n this.destroyBall(ab);\n }\n }\n }\n\n destroyBall(ab)\n {\n const i = this.activeBalls.indexOf(ab);\n\n if (i != -1)\n {\n b2DestroyBody(ab.id);\n this.activeBalls.splice(i, 1);\n\n return true;\n }\n\n return false;\n }\n}\n\nexport class Spinner\n{\n constructor(position, torque, speed, color, size = 1.0, worldId)\n {\n // centre circle, static\n const bodyDefBall = b2DefaultBodyDef();\n bodyDefBall.type = b2BodyType.b2_staticBody;\n bodyDefBall.position = position;\n \n const ballId = b2CreateBody(worldId, bodyDefBall);\n const ball = new b2Circle();\n ball.center = new b2Vec2(0, 0);\n ball.radius = 2.0 * size;\n const shapeDefBall = b2DefaultShapeDef();\n shapeDefBall.density = 1.0;\n shapeDefBall.friction = 0.05;\n shapeDefBall.filter.maskBits = 0x00000000;\n shapeDefBall.customColor = color;\n b2CreateCircleShape(ballId, shapeDefBall, ball);\n\n // paddle, fixed to circle with a revolute joint\n const paddleDef = b2DefaultBodyDef();\n paddleDef.type = b2BodyType.b2_dynamicBody;\n paddleDef.position = position;\n paddleDef.fixedRotation = false;\n const boxId = b2CreateBody(worldId, paddleDef);\n const dynamicBox = b2MakeBox(12 * size, 0.5 * size);\n const shapeDefBox = b2DefaultShapeDef();\n shapeDefBox.density = 5.0;\n shapeDefBox.friction = 1.0;\n shapeDefBox.customColor = color;\n b2CreatePolygonShape(boxId, shapeDefBox, dynamicBox);\n \n const jointDef = b2DefaultRevoluteJointDef();\n jointDef.bodyIdA = boxId;\n jointDef.bodyIdB = ballId;\n jointDef.localAnchorA = new b2Vec2(0, 0);\n jointDef.localAnchorB = new b2Vec2(0, 0); // position;\n jointDef.enableMotor = true;\n jointDef.motorSpeed = speed;\n jointDef.maxMotorTorque = torque;\n b2CreateRevoluteJoint(worldId, jointDef);\n }\n}\n", "/**\n * FUNCTIONS\n */\n\n// Maths\nexport {\n b2MinFloat, b2MaxFloat, b2AbsFloat, b2ClampFloat, b2MinInt, b2MaxInt, b2AbsInt, b2ClampInt,\n b2Dot, b2Cross, b2CrossVS, b2CrossSV, b2LeftPerp, b2RightPerp,\n b2Add, b2Sub, b2Neg, b2Lerp, b2Mul, b2MulSV, b2MulAdd, b2MulSub, b2Abs,\n b2Min, b2Max, b2Clamp, b2Length, b2LengthSquared, b2Distance, b2DistanceSquared,\n b2MakeRot, b2NormalizeRot, b2IsNormalized, b2NLerp, b2IntegrateRotation,\n b2ComputeAngularVelocity, b2Rot_GetAngle, b2Rot_GetXAxis, b2Rot_GetYAxis, b2MulRot, b2InvMulRot,\n b2RelativeAngle, b2UnwindAngle, b2RotateVector, b2InvRotateVector,\n b2TransformPoint, b2InvTransformPoint, b2MulTransforms, b2InvMulTransforms, b2MulMV,\n b2GetInverse22, b2Solve22,\n b2AABB_Contains, b2AABB_Center, b2AABB_Extents, b2AABB_Union\n} from './include/math_functions_h.js';\n\n// Core System\nexport {\n b2SetAllocator,\n b2GetByteCount,\n b2SetAssertFcn,\n b2GetVersion,\n b2CreateTimer,\n b2GetTicks,\n b2GetMilliseconds,\n b2GetMillisecondsAndReset,\n b2SleepMilliseconds,\n b2Yield,\n b2SetLengthUnitsPerMeter,\n b2GetLengthUnitsPerMeter,\n B2_NULL_INDEX\n} from './include/core_h.js';\n\nexport {\n B2_ID_EQUALS,\n B2_IS_NULL,\n B2_IS_NON_NULL\n} from './include/id_h.js';\n\n// World Management\nexport {\n b2CreateWorld,\n b2CreateWorldArray,\n b2DestroyWorld,\n b2World_IsValid,\n b2World_Step,\n b2World_Draw,\n b2World_GetBodyEvents,\n b2World_GetSensorEvents,\n b2World_GetContactEvents,\n b2World_SetGravity,\n b2World_GetGravity,\n b2World_GetProfile,\n b2World_GetCounters,\n b2World_OverlapAABB,\n b2World_OverlapCircle,\n b2World_OverlapCapsule,\n b2World_OverlapPolygon,\n b2World_CastRay,\n b2World_CastRayClosest,\n b2World_CastCircle,\n b2World_CastCapsule,\n b2World_CastPolygon,\n b2World_EnableSleeping,\n b2World_EnableContinuous,\n b2World_SetRestitutionThreshold,\n b2World_SetHitEventThreshold,\n b2World_SetCustomFilterCallback,\n b2World_SetPreSolveCallback,\n b2World_Explode,\n b2World_SetContactTuning,\n b2World_EnableWarmStarting,\n b2World_DumpMemoryStats\n} from './include/world_h.js';\n\n// Body Management\nexport {\n b2Body_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateBody,\n b2DestroyBody,\n b2Body_GetType,\n b2Body_SetType,\n b2Body_GetPosition,\n b2Body_GetRotation,\n b2Body_GetTransform,\n b2Body_SetTransform,\n b2Body_ApplyForce,\n b2Body_ApplyTorque,\n b2Body_ApplyLinearImpulse,\n b2Body_ApplyAngularImpulse,\n b2Body_SetUserData,\n b2Body_GetUserData,\n b2Body_GetLocalPoint,\n b2Body_GetWorldPoint,\n b2Body_GetLocalVector,\n b2Body_GetWorldVector,\n b2Body_GetLinearVelocity,\n b2Body_GetAngularVelocity,\n b2Body_SetLinearVelocity,\n b2Body_SetAngularVelocity,\n b2Body_ApplyForceToCenter,\n b2Body_ApplyLinearImpulseToCenter,\n b2Body_GetMass,\n b2Body_GetRotationalInertia,\n b2Body_GetLocalCenterOfMass,\n b2Body_GetWorldCenterOfMass,\n b2Body_SetMassData,\n b2Body_GetMassData,\n b2Body_ApplyMassFromShapes,\n b2Body_SetLinearDamping,\n b2Body_GetLinearDamping,\n b2Body_SetAngularDamping,\n b2Body_GetAngularDamping,\n b2Body_SetGravityScale,\n b2Body_GetGravityScale,\n b2Body_IsAwake,\n b2Body_SetAwake,\n b2Body_EnableSleep,\n b2Body_IsSleepEnabled,\n b2Body_SetSleepThreshold,\n b2Body_GetSleepThreshold,\n b2Body_IsEnabled,\n b2Body_Disable,\n b2Body_Enable,\n b2Body_SetFixedRotation,\n b2Body_IsFixedRotation,\n b2Body_SetBullet,\n b2Body_IsBullet,\n b2Body_EnableHitEvents,\n b2Body_GetShapeCount,\n b2Body_GetShapes,\n b2Body_GetJointCount,\n b2Body_GetJoints,\n b2Body_GetContactCapacity,\n b2Body_GetContactData,\n b2Body_ComputeAABB\n} from './include/body_h.js';\n\n// Shape Management\nexport {\n b2Shape_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateCircleShape,\n b2CreateSegmentShape,\n b2CreateCapsuleShape,\n b2CreatePolygonShape,\n b2DestroyShape,\n b2Shape_GetType,\n b2Shape_TestPoint,\n b2Shape_RayCast,\n b2Shape_GetBody,\n b2Shape_IsSensor,\n b2Shape_SetUserData,\n b2Shape_GetUserData,\n b2Shape_SetDensity,\n b2Shape_GetDensity,\n b2Shape_SetFriction,\n b2Shape_GetFriction,\n b2Shape_SetRestitution,\n b2Shape_GetRestitution,\n b2Shape_GetFilter,\n b2Shape_SetFilter,\n b2Shape_EnableSensorEvents,\n b2Shape_AreSensorEventsEnabled,\n b2Shape_EnableContactEvents,\n b2Shape_AreContactEventsEnabled,\n b2Shape_EnablePreSolveEvents,\n b2Shape_ArePreSolveEventsEnabled,\n b2Shape_EnableHitEvents,\n b2Shape_AreHitEventsEnabled,\n b2Shape_GetCircle,\n b2Shape_GetSegment,\n b2Shape_GetChainSegment,\n b2Shape_GetCapsule,\n b2Shape_GetPolygon,\n b2Shape_SetCircle,\n b2Shape_SetCapsule,\n b2Shape_SetSegment,\n b2Shape_SetPolygon,\n b2Shape_GetParentChain,\n b2Shape_GetContactCapacity,\n b2Shape_GetContactData,\n b2Shape_GetAABB,\n b2Shape_GetClosestPoint\n} from './include/shape_h.js';\n\n// Joint Management\nexport {\n b2Joint_IsValid\n} from './include/world_h.js';\n\nexport {\n b2CreateDistanceJoint,\n b2CreateMotorJoint,\n b2CreateMouseJoint,\n b2CreatePrismaticJoint,\n b2CreateRevoluteJoint,\n b2CreateWeldJoint,\n b2CreateWheelJoint,\n b2DestroyJoint,\n b2Joint_GetType,\n b2Joint_GetBodyA,\n b2Joint_GetBodyB,\n b2Joint_GetLocalAnchorA,\n b2Joint_GetLocalAnchorB,\n b2Joint_SetCollideConnected,\n b2Joint_GetCollideConnected,\n b2Joint_SetUserData,\n b2Joint_GetUserData,\n b2Joint_WakeBodies,\n b2Joint_GetConstraintForce,\n b2Joint_GetConstraintTorque\n} from './include/joint_h.js';\n\nexport {\n b2DistanceJoint_SetLength,\n b2DistanceJoint_GetLength,\n b2DistanceJoint_EnableSpring,\n b2DistanceJoint_IsSpringEnabled,\n b2DistanceJoint_SetSpringHertz,\n b2DistanceJoint_SetSpringDampingRatio,\n b2DistanceJoint_GetSpringHertz,\n b2DistanceJoint_GetSpringDampingRatio,\n b2DistanceJoint_EnableLimit,\n b2DistanceJoint_IsLimitEnabled,\n b2DistanceJoint_SetLengthRange,\n b2DistanceJoint_GetMinLength,\n b2DistanceJoint_GetMaxLength,\n b2DistanceJoint_GetCurrentLength,\n b2DistanceJoint_EnableMotor,\n b2DistanceJoint_IsMotorEnabled,\n b2DistanceJoint_SetMotorSpeed,\n b2DistanceJoint_GetMotorSpeed,\n b2DistanceJoint_SetMaxMotorForce,\n b2DistanceJoint_GetMaxMotorForce,\n b2DistanceJoint_GetMotorForce\n} from './include/distance_joint_h.js';\n\nexport {\n b2MotorJoint_SetLinearOffset,\n b2MotorJoint_GetLinearOffset,\n b2MotorJoint_SetAngularOffset,\n b2MotorJoint_GetAngularOffset,\n b2MotorJoint_SetMaxForce,\n b2MotorJoint_GetMaxForce,\n b2MotorJoint_SetMaxTorque,\n b2MotorJoint_GetMaxTorque,\n b2MotorJoint_SetCorrectionFactor,\n b2MotorJoint_GetCorrectionFactor\n} from './include/motor_joint_h.js';\n\nexport {\n b2MouseJoint_SetTarget,\n b2MouseJoint_GetTarget,\n b2MouseJoint_SetSpringHertz,\n b2MouseJoint_GetSpringHertz,\n b2MouseJoint_SetSpringDampingRatio,\n b2MouseJoint_GetSpringDampingRatio,\n b2MouseJoint_SetMaxForce,\n b2MouseJoint_GetMaxForce\n} from './include/mouse_joint_h.js';\n\nexport {\n b2PrismaticJoint_EnableSpring,\n b2PrismaticJoint_IsSpringEnabled,\n b2PrismaticJoint_SetSpringHertz,\n b2PrismaticJoint_GetSpringHertz,\n b2PrismaticJoint_SetSpringDampingRatio,\n b2PrismaticJoint_GetSpringDampingRatio,\n b2PrismaticJoint_EnableLimit,\n b2PrismaticJoint_IsLimitEnabled,\n b2PrismaticJoint_GetLowerLimit,\n b2PrismaticJoint_GetUpperLimit,\n b2PrismaticJoint_SetLimits,\n b2PrismaticJoint_EnableMotor,\n b2PrismaticJoint_IsMotorEnabled,\n b2PrismaticJoint_SetMotorSpeed,\n b2PrismaticJoint_GetMotorSpeed,\n b2PrismaticJoint_SetMaxMotorForce,\n b2PrismaticJoint_GetMaxMotorForce,\n b2PrismaticJoint_GetMotorForce\n} from './include/prismatic_joint_h.js';\n\nexport {\n b2RevoluteJoint_EnableSpring,\n b2RevoluteJoint_SetSpringHertz,\n b2RevoluteJoint_GetSpringHertz,\n b2RevoluteJoint_SetSpringDampingRatio,\n b2RevoluteJoint_GetSpringDampingRatio,\n b2RevoluteJoint_GetAngle,\n b2RevoluteJoint_EnableLimit,\n b2RevoluteJoint_IsLimitEnabled,\n b2RevoluteJoint_GetLowerLimit,\n b2RevoluteJoint_GetUpperLimit,\n b2RevoluteJoint_SetLimits,\n b2RevoluteJoint_EnableMotor,\n b2RevoluteJoint_IsMotorEnabled,\n b2RevoluteJoint_SetMotorSpeed,\n b2RevoluteJoint_GetMotorSpeed,\n b2RevoluteJoint_GetMotorTorque,\n b2RevoluteJoint_SetMaxMotorTorque,\n b2RevoluteJoint_GetMaxMotorTorque,\n b2RevoluteJoint_IsSpringEnabled\n} from './include/revolute_joint_h.js';\n\nexport {\n b2WeldJoint_SetLinearHertz,\n b2WeldJoint_GetLinearHertz,\n b2WeldJoint_SetLinearDampingRatio,\n b2WeldJoint_GetLinearDampingRatio,\n b2WeldJoint_SetAngularHertz,\n b2WeldJoint_GetAngularHertz,\n b2WeldJoint_SetAngularDampingRatio,\n b2WeldJoint_GetAngularDampingRatio\n} from './include/weld_joint_h.js';\n\nexport {\n b2WheelJoint_EnableSpring,\n b2WheelJoint_IsSpringEnabled,\n b2WheelJoint_SetSpringHertz,\n b2WheelJoint_GetSpringHertz,\n b2WheelJoint_SetSpringDampingRatio,\n b2WheelJoint_GetSpringDampingRatio,\n b2WheelJoint_EnableLimit,\n b2WheelJoint_IsLimitEnabled,\n b2WheelJoint_GetLowerLimit,\n b2WheelJoint_GetUpperLimit,\n b2WheelJoint_SetLimits,\n b2WheelJoint_EnableMotor,\n b2WheelJoint_IsMotorEnabled,\n b2WheelJoint_SetMotorSpeed,\n b2WheelJoint_GetMotorSpeed,\n b2WheelJoint_SetMaxMotorTorque,\n b2WheelJoint_GetMaxMotorTorque,\n b2WheelJoint_GetMotorTorque\n} from './include/wheel_joint_h.js';\n\n// Collision Detection\nexport {\n b2CollideCircles,\n b2CollideCapsules,\n b2CollidePolygons,\n b2CollideCapsuleAndCircle,\n b2CollidePolygonAndCircle,\n b2CollideSegmentAndCapsule,\n b2CollidePolygonAndCapsule,\n b2CollideSegmentAndCircle,\n b2CollideSegmentAndPolygon,\n b2CollideChainSegmentAndCircle,\n b2CollideChainSegmentAndCapsule,\n b2CollideChainSegmentAndPolygon\n} from './include/manifold_h.js';\n\nexport {\n b2RayCastCircle,\n b2RayCastPolygon,\n b2RayCastCapsule,\n b2RayCastSegment,\n b2ShapeCastCircle,\n b2ShapeCastCapsule,\n b2ShapeCastSegment,\n b2ShapeCastPolygon,\n b2IsValidRay\n} from './include/geometry_h.js';\n\nexport {\n b2ShapeCast,\n b2TimeOfImpact\n} from './include/distance_h.js';\n\n// Math & Utilities\nexport {\n b2IsValid,\n b2Vec2_IsValid,\n b2Rot_IsValid,\n b2AABB_IsValid,\n b2Normalize,\n b2NormalizeChecked,\n b2GetLengthAndNormalize\n} from './include/math_functions_h.js';\n\nexport {\n b2ComputeHull,\n b2ValidateHull\n} from './include/hull_h.js';\n\nexport {\n b2SegmentDistance,\n b2ShapeDistance,\n b2MakeProxy,\n b2GetSweepTransform\n} from './include/distance_h.js';\n\nexport {\n b2MakePolygon,\n b2MakeOffsetPolygon,\n b2MakeSquare,\n b2MakeBox,\n b2MakeRoundedBox,\n b2MakeOffsetBox,\n b2TransformPolygon,\n b2ComputeCircleMass,\n b2ComputeCapsuleMass,\n b2ComputePolygonMass,\n b2ComputeCircleAABB,\n b2ComputeCapsuleAABB,\n b2ComputePolygonAABB,\n b2ComputeSegmentAABB,\n b2PointInCircle,\n b2PointInCapsule,\n b2PointInPolygon\n} from './include/geometry_h.js';\n\n// Chain\nexport {\n b2CreateChain,\n b2Chain_SetFriction,\n b2Chain_SetRestitution,\n b2DestroyChain\n} from './include/shape_h.js';\n\nexport {\n b2Chain_IsValid\n} from './include/world_h.js';\n\n// Dynamic Tree\nexport {\n b2DynamicTree_Create,\n b2DynamicTree_Destroy,\n b2DynamicTree_CreateProxy,\n b2DynamicTree_DestroyProxy,\n b2DynamicTree_MoveProxy,\n b2DynamicTree_EnlargeProxy,\n b2DynamicTree_Query,\n b2DynamicTree_RayCast,\n b2DynamicTree_ShapeCast,\n b2DynamicTree_Validate,\n b2DynamicTree_GetHeight,\n b2DynamicTree_GetMaxBalance,\n b2DynamicTree_GetAreaRatio,\n b2DynamicTree_RebuildBottomUp,\n b2DynamicTree_GetProxyCount,\n b2DynamicTree_Rebuild,\n b2DynamicTree_ShiftOrigin,\n b2DynamicTree_GetByteCount\n} from './include/dynamic_tree_h.js';\n\n// Default Definitions\nexport {\n b2DefaultWorldDef,\n b2DefaultBodyDef,\n b2DefaultFilter,\n b2DefaultQueryFilter,\n b2DefaultShapeDef,\n b2DefaultChainDef\n} from './include/types_h.js';\n\nexport {\n b2DefaultDistanceJointDef,\n b2DefaultMotorJointDef,\n b2DefaultMouseJointDef,\n b2DefaultPrismaticJointDef,\n b2DefaultRevoluteJointDef,\n b2DefaultWeldJointDef,\n b2DefaultWheelJointDef\n} from './include/joint_h.js';\n\n// Phaser Additions v2\n\nexport const STATIC = 0;\nexport const KINEMATIC = 1;\nexport const DYNAMIC = 2;\n\nexport {\n GetWorldScale,\n SetWorldScale,\n mpx,\n pxm,\n pxmVec2,\n RotFromRad,\n BodyToSprite,\n SpriteToBox,\n SpriteToCircle,\n AddSpriteToWorld,\n RemoveSpriteFromWorld,\n ClearWorldSprites,\n GetBodyFromSprite,\n UpdateWorldSprites,\n CreateBoxPolygon,\n CreateCapsule,\n CreateChain,\n CreateCircle,\n CreateDistanceJoint,\n CreateMotorJoint,\n CreateMouseJoint,\n CreateNGonPolygon,\n CreatePolygon,\n CreatePolygonFromEarcut,\n CreatePolygonFromVertices,\n CreatePhysicsEditorShape,\n CreatePrismaticJoint,\n CreateRevoluteJoint,\n CreateWeldJoint,\n CreateWheelJoint,\n CreateWorld,\n WorldStep\n} from './physics.js';\n\n// Debug Draw (remove from prod bundle)\nexport {\n AttachImage,\n ConvertScreenToWorld,\n ConvertWorldToScreen,\n CreateDebugDraw,\n RAF\n} from './debug_draw.js';\n\nexport {\n Ragdoll,\n Skeletons\n} from './ragdoll.js';\n\nexport {\n ActiveBall,\n Gun,\n Spinner\n} from './fun_stuff.js';\n\n\n/**\n * \n * TYPES\n * \n */\n\n// World Management\nexport {\n b2WorldDef,\n b2BodyEvents,\n b2SensorEvents,\n b2ContactEvents\n} from './include/types_h.js';\n\nexport {\n b2WorldId\n} from './include/id_h.js';\n\n// Geometry & Math\nexport {\n b2AABB,\n b2Vec2,\n b2Rot,\n b2Transform\n} from './include/math_functions_h.js';\n\nexport {\n b2Hull,\n b2Sweep,\n b2Manifold,\n b2Simplex\n} from './include/collision_h.js';\n\n// Shapes\nexport {\n b2Circle,\n b2Capsule,\n b2Polygon,\n b2Segment,\n b2ChainSegment\n} from './include/collision_h.js';\n\nexport {\n b2ShapeId\n} from './include/id_h.js';\n\nexport {\n b2ShapeDef,\n b2ShapeType,\n b2Filter\n} from './include/types_h.js';\n\n// Bodies\nexport {\n b2BodyDef,\n b2BodyType\n} from './include/types_h.js';\n\nexport {\n b2MassData\n} from './include/collision_h.js';\n\nexport {\n b2BodyId\n} from './include/id_h.js';\n\nexport {\n b2JointId,\n b2ChainId\n} from './include/id_h.js';\n\n// Joints\nexport {\n b2JointType,\n b2DistanceJointDef,\n b2MotorJointDef,\n b2MouseJointDef,\n b2PrismaticJointDef,\n b2RevoluteJointDef,\n b2WeldJointDef,\n b2WheelJointDef\n} from './include/types_h.js';\n\n// Chains\nexport {\n b2ChainDef\n} from './include/types_h.js';\n\n// Collision Detection\nexport {\n b2QueryFilter,\n b2RayResult,\n b2ContactData\n} from './include/types_h.js';\n\nexport {\n b2CastOutput,\n b2RayCastInput,\n b2SegmentDistanceResult,\n b2DistanceCache,\n b2DistanceInput,\n b2DistanceOutput,\n b2DistanceProxy,\n b2ShapeCastInput,\n b2ShapeCastPairInput,\n b2TOIInput,\n b2TOIOutput\n} from './include/collision_h.js';\n\n// Broad-phase\nexport {\n b2DynamicTree\n} from './include/dynamic_tree_h.js';\n\n// Callbacks\nexport {\n b2DebugDraw\n} from './include/types_h.js';\n\n// Enumerations\nexport {\n b2HexColor\n} from './include/types_h.js';\n"], + "mappings": "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", "names": ["c", "p", "q", "xf", "q1", "q2", "b2_lengthUnitsPerMeter", "b2_lengthUnitsPerMeter", "c", "p1", "p2", "b2_lengthUnitsPerMeter", "xf", "q", "p", "localPointB", "pointA", "pointB", "normal", "s", "p1", "p2", "c", "p1", "p2", "p", "p3", "xf", "p", "p1", "p2", "sv", "c", "rayPoint", "rayNormal", "q", "output", "shape", "xf", "rayPoint", "rayNormal", "rayNormal", "rayPoint", "stack", "p1", "p2", "c", "child1", "child2", "contactId", "c", "p1", "p2", "xf1", "q", "b2_lengthUnitsPerMeter", "translation", "p", "stack", "set", "aabb", "shapeId", "p1", "p2", "p", "p0", "p1", "p2", "ib1", "ib2", "b1", "b2", "pAB", "p", "centerOffsetA", "centerOffsetB", "p1", "p2", "xf", "p", "b2GetBit", "b2GetBit", "c", "xf", "p", "url", "key", "p0", "xf", "ctx", "p1", "p2"] } diff --git a/dist/PhaserBox2D.js b/dist/PhaserBox2D.js index b68aa07..87e3c6d 100644 --- a/dist/PhaserBox2D.js +++ b/dist/PhaserBox2D.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:39 + * Saturday, 18 January 2025 at 09:17 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is @@ -15975,6 +15975,7 @@ function CreatePolygonFromVertices(data) { b2CreatePolygonShape(body.bodyId, shapeDef, nGon); } }); + return body; } function CreatePhysicsEditorShape(data) { const key = data.key; diff --git a/dist/PhaserBox2D.min.js b/dist/PhaserBox2D.min.js index 2568dc1..c43be6d 100644 --- a/dist/PhaserBox2D.min.js +++ b/dist/PhaserBox2D.min.js @@ -1,11 +1,11 @@ /** * @license * Phaser Box2D v1.1.0 - * Tuesday, 14 January 2025 at 17:39 + * Saturday, 18 January 2025 at 09:17 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is * Copyright 2025 Phaser Studio Inc and is released under the MIT license. */ -function Ye(t){let e=Yt(t);if(ee?t:e}function D2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function P2(t,e){return te?t:e}function T2(t){return t<0?-t:t}function G2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function de(t){return new g(-t.y,t.x)}function be(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function R2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function vi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function Ji(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Mi(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function L2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function pe(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function ue(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Di(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function E2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function wi(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function F2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function X2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function q2(t){return Math.atan2(t.s,t.c)}function V2(t){return new g(t.c,t.s)}function Y2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function N2(t,e){return t.c*e.c-t.s*e.s}function W2(t,e){return t.s*e.c+t.c*e.s}function O2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function vo(t){return t<-wo?t+2*wo:t>wo?t-2*wo:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function U2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function z2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function ki(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function Jo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function K2(t){return t&&ae(t.s)&&ae(t.c)&&wi(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function lt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function H2(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Q2=1,x=-1;function Ta(t){Q2=t}function Ga(){return Q2}function Ra(t){}function La(){return new Ti(3,1,0)}var We=1,De=1e5*We,te=2,It=.005*We;var Z2=.25*Math.PI,Qt=4*It,vn=.1*We,th=.5;function eh(){}function oh(){}function nh(){}function sh(){}function rh(){}function ih(t){}function ah(t){}function ch(){}var co=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function lh(t){return t.index1===0}function dh(t){return t.index1!==0}function bh(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function pm(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?de(e):be(e);default:return new g(0,0)}}function mm(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function hh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function mh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function yh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=pm(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=yo(o,Ht(y)),h=o.points[u],m=yo(i,y),f=i.points[m];let v=J(h,f);y=lt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:mh(p);break;case 3:yh(p);break;default:}if(p.count===3)return e;y=mm(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;hh(B,A,p);let w=lt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function xm(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new bo,Object.assign(i.sweepA,o),i.sweepB=new bo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=lt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=lt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=lt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Im(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=yo(t.proxyA,s),c=yo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=yo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=yo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function uh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new he;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=uh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=lt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=ue(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=lt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new lo;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new lo;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new lo;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function Ih(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation||n.isSensor)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(ue(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function fo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function za(t,e,o){return ue(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function Sh(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&xo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ka(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);Sh(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function Ha(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&xo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function mc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function fc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function xc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Ic(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function Sc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function _c(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Bc(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Ac(t){let e=O(t.world0);return Bt(e,t).type}function Cc(t){let e=O(t.world0);return Bt(e,t).circle}function wc(t){let e=O(t.world0);return Bt(e,t).segment}function vc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Jc(t){let e=O(t.world0);return Bt(e,t).capsule}function Mc(t){let e=O(t.world0);return Bt(e,t).polygon}function Dc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Gc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Rc(t,e){let o=ft(t.world0);if(o===null)return;let n=Ih(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Fc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function Xc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new he;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new ho,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,dt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=dt>0?1/dt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Nc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,dt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*dt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(dt*ut-Et*Ge)}for(let ot=0;otdt?dt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var vm=1024;function Bh(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&sl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=lt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Mm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(vm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:gh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:gh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Mm(t,o),o}function Ch(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=il(o.bodyCount),i.contacts=al(o.contactCount),i.joints=cl(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(Io(C.bodySet,y.edges[0].bodyId),Io(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(Io(_.bodySet,y.edges[0].bodyId),Io(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function rl(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function Pm(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,Jo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Tm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Dm(s,r,e):n===yn.b2_stageIntegratePositions&&Pm(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Rm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new bl;N.context=e,N.workerIndex=0,Gm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&Em(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&jm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(_h(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function fl(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function xl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function _l(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Bl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function Al(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=le(o,e.bodyIdA),s=le(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function Cl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function wl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Ml(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function Dl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Pl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Tl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function Rl(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function Ll(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function El(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function jl(t,e){let o=e.distanceJoint,n=le(t,e.bodyIdA),s=le(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=lt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function Fl(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=lt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Xl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=lt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function ql(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=lt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Vl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=lt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Yl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Nl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function $l(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function Zl(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function td(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function ed(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function od(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function sd(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function rd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function id(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ad(t,e){let o=e.bodyIdA,n=le(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=de(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function cd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function dd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=de(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function bd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=de(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function pd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function ud(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function hd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function Id(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=le(e,o.bodyIdA),s=le(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=vo(r),r}function Sd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function _d(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function gd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function Ad(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function Cd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function wd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function vd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Md(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function Dd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Pd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function kd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Td(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Gd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=vo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Rd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function Ld(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=vo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Ed(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function jd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function Fd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Xd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function Od(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function zd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function Kd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Hd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function Zd(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function tb(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function eb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function ob(t,e){let o=e.wheelJoint,n=o.axisA,s=de(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function nb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=de(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function rb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=de(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function ib(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=de(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function ab(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function cb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function lb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-wo,wo)}function bb(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function xb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function Ib(t,e){return t.inv_h*e.motorJoint.angularImpulse}function Sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=vo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function _b(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function gb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=vo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),pe(a.linearImpulse)>w*w&&(a.linearImpulse=lt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Bb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function Ab(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function Cb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Pb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function kb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Tb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Gb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Rb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,lt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function Lb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Eb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Nb(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Wb(t,e){return t.inv_h*e.weldJoint.angularImpulse}function Ob(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Ub(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function zb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Hb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function $b(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function Qb(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function Zb(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new mo;return t.drawSize=.25,t}function tp(){return new tn}function ep(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var Kb=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function Kn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new zn,new zn],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(rl(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p,!0),Lt(t),new Kb(p,h)}function Hn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&xo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=Kn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=lt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=lt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,e.islandId!==x&&Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function op(t){let e=O(t.world0);return Je(e,t).type}function np(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function sp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function rp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function ip(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function ap(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){up(t,i,e);return}let a=null;if(i!==x){a=go(t,i);let d=a.parentIsland;for(;d!==x;){let p=go(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=go(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=go(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?up(t,i,e):up(t,c,e)}function ri(t,e){let o=e.islandId,n=go(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function hp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,Bo(t,e)}function Ys(t,e,o){let n=_t(t,e.edges[0].bodyId),s=_t(t,e.edges[1].bodyId);n.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet?qe(t,s.setIndex):s.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet&&qe(t,n.setIndex);let r=n.islandId,i=s.islandId;if(r===i){hp(t,r,e);return}let c=null;if(r!==x)for(c=go(t,r);c.parentIsland!==x;){let l=go(t,c.parentIsland);l.parentIsland!==x&&(c.parentIsland=l.parentIsland),r=c.parentIsland,c=l}let a=null;if(i!==x)for(a=go(t,i);a.parentIsland!==x;){let l=go(t,a.parentIsland);l.parentIsland!==x&&(a.parentIsland=l.parentIsland),i=a.parentIsland,a=l}c!==a&&c!==null&&a!==null&&(a.parentIsland=r),c!==null?hp(t,r,e):hp(t,i,e),o&&Un(t)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function qm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,Bo(t,o)}function Un(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(qm(t,c),si(t,i))}ii(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;Bo(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}Bo(t,f)}}function Bo(t,e){if(!uo)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function le(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function yp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function fp(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&Bo(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function xp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,xo(t,i,o)}Lt(t)}function Ao(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&yp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}xp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}fp(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function Ip(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function Sp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function _p(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=le(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=Za(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function gp(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ai(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Bp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function Ap(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,Jo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function wp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function vp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Jp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;pe(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Mp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function Dp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Pp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Gp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Rp(t){let e=O(t.world0);return Z(e,t).type}function Lp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}xp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),yp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?_o(o,c,i,u):u.setIndex===M.b2_awakeSet&&(_o(o,i,c,u),_o(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),fp(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?_o(o,i,c,u):(_o(o,i,c,u),_o(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l,!1))}Un(o)}cn(o,n),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Ep(t){let e=O(t.world0);return Z(e,t).userData}function jp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function Fp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Vp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Yp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Np(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Wp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function Op(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function $p(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function Qp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function tu(t){let e=O(t.world0);return Z(e,t).enableSleep}function eu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function ou(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function nu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function su(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;xp(e,o,!0),fp(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];_o(e,i,p,d)}ii(e),Lt(e)}function ru(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let b=e.shapeArray[l];l=b.nextShapeId,Vn(b,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&yp(e,s,o);let d=!1,p=o.headJointKey;for(;p!==x;){let b=p>>1,u=p&1,h=e.jointArray[b];p=h.edges[u].nextKey;let m=e.bodyArray[h.edges[0].bodyId],f=e.bodyArray[h.edges[1].bodyId];if(m.setIndex===M.b2_disabledSet||f.setIndex===M.b2_disabledSet)continue;let y;m.setIndex===M.b2_staticSet&&f.setIndex===M.b2_staticSet?y=M.b2_staticSet:m.setIndex===M.b2_staticSet?y=f.setIndex:y=m.setIndex;let I=e.solverSetArray[y];_o(e,I,n,h),y!==M.b2_staticSet&&Ys(e,h,d)}Un(e),Lt(e)}function iu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function au(t){let e=O(t.world0);return Z(e,t).fixedRotation}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function lu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function du(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function bu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function pu(t){let e=O(t.world0);return Z(e,t).jointCount}function uu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Co=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function il(t){let e=new Es(t);return t>0?(e.data=po(t,()=>new Hs),e):(e.data=null,e)}function al(t){let e=new ln(t);return t>0?(e.data=po(t,()=>new Qn),e):(e.data=null,e)}function cl(t){let e=new dn(t);return t>0?(e.data=po(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=po(Co,()=>new Hs),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=po(Co,()=>new Pt),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=po(Co,()=>new Qn),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=po(Co,()=>new Ws),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=po(Co,()=>new Os),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ci(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),hu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function Su(t,e,o){let n=J(e,t),s=lt(n),r=be(s),i=new ge;return i.vertices=[t,e],i.centroid=$t(t,e,.5),i.normals=[r,Ht(r)],i.count=2,i.radius=o,i}function li(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function di(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;vi(e.p,1,K(e.q,r),hu.p),hu.q=e.q,Uo(hu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=ue(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let dt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let dt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let dt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);dt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);dt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,dt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+dt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;vi(D,.5*(R-X-P),b,pt),vi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function kh(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),mu=new g,yu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;mu.x=e.p.x+(e.q.c*r-e.q.s*i),mu.y=e.p.y+(e.q.s*r+e.q.c*i),yu.p=mu,yu.q=e.q,Uo(yu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else Ph(kt,Ut,a,p,h,s)}else Ph(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function yi(t,e,o,n,s,r){let i=Su(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function fu(t,e,o,n,s,r,i,c,a,l){let d=de(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function xu(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var Iu=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=lt(J(l,a)),p=new Iu;p.edge1=d.clone();let b=.01,u=lt(J(a,t.ghost1));p.normal0=be(u),p.convex1=z(u,d)>=b;let h=lt(J(t.ghost2,l));p.normal2=be(h),p.convex2=z(d,h)>=b;let m=be(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=lt(J(et,W)),ot=xu(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=xu(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new gu)),Th=!1;function Nm(t,e,o,n,s,r){return li(t.circle,e,o.circle,n,r)}function Wm(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function Um(t,e,o,n,s,r){return di(t.polygon,e,o.circle,n,r)}function zm(t,e,o,n,s,r){return pi(t.polygon,e,o.capsule,n,r)}function Km(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function Hm(t,e,o,n,s,r){return ui(t.segment,e,o.circle,n,r)}function $m(t,e,o,n,s,r){return bi(t.segment,e,o.capsule,n,r)}function Qm(t,e,o,n,s,r){return hi(t.segment,e,o.polygon,n,r)}function Zm(t,e,o,n,s,r){return mi(t.chainSegment,e,o.circle,n,r)}function ty(t,e,o,n,s,r){return yi(t.chainSegment,e,o.capsule,n,s,r)}function ey(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Bu(){Th===!1&&(Ve(Nm,Y.b2_circleShape,Y.b2_circleShape),Ve(Wm,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(Um,Y.b2_polygonShape,Y.b2_circleShape),Ve(zm,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Km,Y.b2_polygonShape,Y.b2_polygonShape),Ve(Hm,Y.b2_segmentShape,Y.b2_circleShape),Ve($m,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(Zm,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_polygonShape),Th=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Vm(e.friction,o.friction),h.restitution=Ym(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function xo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function oy(t,e,o,n,s){let r=new he;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var _u=new To;function Au(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=oy(o,n,r,i,e.cache);else{e.manifold.copyTo(_u);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Ju=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Mu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function ny(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew wu),sy(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function sy(t,e,o){let n=o.broadPhase,s=new vu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,cy(s),s.dt>0&&ul(n,s),n.locked=!1}var An=new g,ts=new g,ly=new rt,Ru=new at(An,ly);function Lh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;U2(s,r.center,Ru),e.image?t.DrawImageCircle(Ru,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Ru,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var ju=class{constructor(e,o){this.world=e,this.draw=o}};function dy(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Lh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function by(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new ju(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Rh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Rh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=be(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Vu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){by(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Lh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=be(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Yu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Nu(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Wu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function Ou(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function Qu(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function Zu(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function t2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function e2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function o2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function py(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var Fu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function n2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new Fu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function r2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Si;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function c2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Qa(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=lt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function x2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Xu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,hy,r)}function Lu(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function ii(t){if(!uo)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=Lu(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=Lu(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!uo)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Fh(){}function Xh(){}function qh(){}var Tg=new g;var I2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Ai({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new I2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new mo;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{_2(e,o)})}function _2(t,e){let o=ai(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function $h(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=B2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=g2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t){let e=t.worldDef;return e||(e=lr()),_i(),{worldId:gi(e)}}var Ja=0;function tm(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=le(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=fo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function nm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function A2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function sm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ci(t){let e=t.jointDef;return e||(e=new mo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function rm(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function im(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var fA=0,xA=1,IA=2;export{Oh as AddSpriteToWorld,bh as B2_ID_EQUALS,dh as B2_IS_NON_NULL,lh as B2_IS_NULL,x as B2_NULL_INDEX,_2 as BodyToSprite,zh as ClearWorldSprites,B2 as CreateBoxPolygon,Ai as CreateCapsule,em as CreateChain,g2 as CreateCircle,im as CreateDistanceJoint,lm as CreateMotorJoint,dm as CreateMouseJoint,om as CreateNGonPolygon,sm as CreatePhysicsEditorShape,va as CreatePolygon,nm as CreatePolygonFromEarcut,A2 as CreatePolygonFromVertices,cm as CreatePrismaticJoint,Ci as CreateRevoluteJoint,rm as CreateWeldJoint,am as CreateWheelJoint,Zh as CreateWorld,IA as DYNAMIC,Kh as GetBodyFromSprite,Yh as GetWorldScale,xA as KINEMATIC,Ca as Ragdoll,Uh as RemoveSpriteFromWorld,wa as RotFromRad,fA as STATIC,Vh as SetWorldScale,Aa as Skeletons,$h as SpriteToBox,Qh as SpriteToCircle,Hh as UpdateWorldSprites,tm as WorldStep,xt as b2AABB,Le as b2AABB_Center,Jo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,D2 as b2AbsFloat,T2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Gp as b2Body_ApplyAngularImpulse,Dp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,kp as b2Body_ApplyLinearImpulse,Tp as b2Body_ApplyLinearImpulseToCenter,Np as b2Body_ApplyMassFromShapes,Pp as b2Body_ApplyTorque,_p as b2Body_ComputeAABB,su as b2Body_Disable,ru as b2Body_Enable,du as b2Body_EnableHitEvents,nu as b2Body_EnableSleep,zp as b2Body_GetAngularDamping,vp as b2Body_GetAngularVelocity,Ip as b2Body_GetContactCapacity,Sp as b2Body_GetContactData,Hp as b2Body_GetGravityScale,pu as b2Body_GetJointCount,uu as b2Body_GetJoints,Op as b2Body_GetLinearDamping,wp as b2Body_GetLinearVelocity,Xp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,Ap as b2Body_GetLocalVector,jp as b2Body_GetMass,Yp as b2Body_GetMassData,gp as b2Body_GetPosition,Us as b2Body_GetRotation,Fp as b2Body_GetRotationalInertia,bu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,ou as b2Body_GetSleepThreshold,ai as b2Body_GetTransform,Rp as b2Body_GetType,Ep as b2Body_GetUserData,qp as b2Body_GetWorldCenterOfMass,Bp as b2Body_GetWorldPoint,Cp as b2Body_GetWorldVector,$p as b2Body_IsAwake,lu as b2Body_IsBullet,Zp as b2Body_IsEnabled,au as b2Body_IsFixedRotation,tu as b2Body_IsSleepEnabled,Uu as b2Body_IsValid,Up as b2Body_SetAngularDamping,Mp as b2Body_SetAngularVelocity,Qp as b2Body_SetAwake,cu as b2Body_SetBullet,iu as b2Body_SetFixedRotation,Kp as b2Body_SetGravityScale,Wp as b2Body_SetLinearDamping,Jp as b2Body_SetLinearVelocity,Vp as b2Body_SetMassData,eu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,Lp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,Ku as b2Chain_IsValid,Rc as b2Chain_SetFriction,Lc as b2Chain_SetRestitution,ce as b2Circle,L2 as b2Clamp,ht as b2ClampFloat,G2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,yi as b2CollideChainSegmentAndCapsule,mi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,li as b2CollideCircles,pi as b2CollidePolygonAndCapsule,di as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,bi as b2CollideSegmentAndCapsule,ui as b2CollideSegmentAndCircle,hi as b2CollideSegmentAndPolygon,X2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Ao as b2CreateBody,qn as b2CreateCapsuleShape,Ha as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,fo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,za as b2CreateSegmentShape,nh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,gi as b2CreateWorld,_i as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Hb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,$b as b2DefaultMotorJointDef,Qb as b2DefaultMouseJointDef,Zb as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,tp as b2DefaultWeldJointDef,ep as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,$a as b2DestroyChain,ni as b2DestroyJoint,Ka as b2DestroyShape,qu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,he as b2DistanceInput,Ho as b2DistanceJointDef,Il as b2DistanceJoint_EnableLimit,Pl as b2DistanceJoint_EnableMotor,Cl as b2DistanceJoint_EnableSpring,Al as b2DistanceJoint_GetCurrentLength,xl as b2DistanceJoint_GetLength,Bl as b2DistanceJoint_GetMaxLength,El as b2DistanceJoint_GetMaxMotorForce,gl as b2DistanceJoint_GetMinLength,Rl as b2DistanceJoint_GetMotorForce,Gl as b2DistanceJoint_GetMotorSpeed,Dl as b2DistanceJoint_GetSpringDampingRatio,Ml as b2DistanceJoint_GetSpringHertz,Sl as b2DistanceJoint_IsLimitEnabled,kl as b2DistanceJoint_IsMotorEnabled,wl as b2DistanceJoint_IsSpringEnabled,fl as b2DistanceJoint_SetLength,_l as b2DistanceJoint_SetLengthRange,Ll as b2DistanceJoint_SetMaxMotorForce,Tl as b2DistanceJoint_SetMotorSpeed,Jl as b2DistanceJoint_SetSpringDampingRatio,vl as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,ue as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Qc as b2DynamicTree_GetAreaRatio,nl as b2DynamicTree_GetByteCount,$c as b2DynamicTree_GetHeight,tl as b2DynamicTree_GetMaxBalance,Hc as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,el as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,ol as b2DynamicTree_ShiftOrigin,Zc as b2DynamicTree_Validate,ho as b2Filter,oh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,rh as b2GetMilliseconds,ih as b2GetMillisecondsAndReset,we as b2GetSweepTransform,sh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,j2 as b2IntegrateRotation,O2 as b2InvMulRot,ki as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,wi as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,np as b2Joint_GetBodyA,sp as b2Joint_GetBodyB,cp as b2Joint_GetCollideConnected,bp as b2Joint_GetConstraintForce,pp as b2Joint_GetConstraintTorque,rp as b2Joint_GetLocalAnchorA,ip as b2Joint_GetLocalAnchorB,op as b2Joint_GetType,dp as b2Joint_GetUserData,Hu as b2Joint_IsValid,ap as b2Joint_SetCollideConnected,lp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,de as b2LeftPerp,Yt as b2Length,pe as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Di as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Mi as b2Max,M2 as b2MaxFloat,k2 as b2MaxInt,Ji as b2Min,J2 as b2MinFloat,P2 as b2MinInt,$o as b2MotorJointDef,bb as b2MotorJoint_GetAngularOffset,fb as b2MotorJoint_GetCorrectionFactor,lb as b2MotorJoint_GetLinearOffset,ub as b2MotorJoint_GetMaxForce,mb as b2MotorJoint_GetMaxTorque,db as b2MotorJoint_SetAngularOffset,yb as b2MotorJoint_SetCorrectionFactor,cb as b2MotorJoint_SetLinearOffset,pb as b2MotorJoint_SetMaxForce,hb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,Db as b2MouseJoint_GetMaxForce,Jb as b2MouseJoint_GetSpringDampingRatio,wb as b2MouseJoint_GetSpringHertz,Ab as b2MouseJoint_GetTarget,Mb as b2MouseJoint_SetMaxForce,vb as b2MouseJoint_SetSpringDampingRatio,Cb as b2MouseJoint_SetSpringHertz,Bb as b2MouseJoint_SetTarget,R2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,z2 as b2MulTransforms,Pi as b2NLerp,Ht as b2Neg,lt as b2Normalize,H2 as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,Kl as b2PrismaticJoint_EnableLimit,td as b2PrismaticJoint_EnableMotor,Yl as b2PrismaticJoint_EnableSpring,$l as b2PrismaticJoint_GetLowerLimit,id as b2PrismaticJoint_GetMaxMotorForce,sd as b2PrismaticJoint_GetMotorForce,nd as b2PrismaticJoint_GetMotorSpeed,zl as b2PrismaticJoint_GetSpringDampingRatio,Ol as b2PrismaticJoint_GetSpringHertz,Ql as b2PrismaticJoint_GetUpperLimit,Hl as b2PrismaticJoint_IsLimitEnabled,ed as b2PrismaticJoint_IsMotorEnabled,Nl as b2PrismaticJoint_IsSpringEnabled,Zl as b2PrismaticJoint_SetLimits,rd as b2PrismaticJoint_SetMaxMotorForce,od as b2PrismaticJoint_SetMotorSpeed,Ul as b2PrismaticJoint_SetSpringDampingRatio,Wl as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,mo as b2RevoluteJointDef,Sd as b2RevoluteJoint_EnableLimit,Cd as b2RevoluteJoint_EnableMotor,ud as b2RevoluteJoint_EnableSpring,Id as b2RevoluteJoint_GetAngle,gd as b2RevoluteJoint_GetLowerLimit,Pd as b2RevoluteJoint_GetMaxMotorTorque,Jd as b2RevoluteJoint_GetMotorSpeed,Md as b2RevoluteJoint_GetMotorTorque,xd as b2RevoluteJoint_GetSpringDampingRatio,yd as b2RevoluteJoint_GetSpringHertz,Bd as b2RevoluteJoint_GetUpperLimit,_d as b2RevoluteJoint_IsLimitEnabled,wd as b2RevoluteJoint_IsMotorEnabled,hd as b2RevoluteJoint_IsSpringEnabled,Ad as b2RevoluteJoint_SetLimits,Dd as b2RevoluteJoint_SetMaxMotorTorque,vd as b2RevoluteJoint_SetMotorSpeed,fd as b2RevoluteJoint_SetSpringDampingRatio,md as b2RevoluteJoint_SetSpringHertz,be as b2RightPerp,rt as b2Rot,q2 as b2Rot_GetAngle,V2 as b2Rot_GetXAxis,Y2 as b2Rot_GetYAxis,K2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,eh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,lo as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Ic as b2Shape_AreContactEventsEnabled,Bc as b2Shape_AreHitEventsEnabled,_c as b2Shape_ArePreSolveEventsEnabled,fc as b2Shape_AreSensorEventsEnabled,xc as b2Shape_EnableContactEvents,gc as b2Shape_EnableHitEvents,Sc as b2Shape_EnablePreSolveEvents,yc as b2Shape_EnableSensorEvents,Fc as b2Shape_GetAABB,oc as b2Shape_GetBody,Jc as b2Shape_GetCapsule,vc as b2Shape_GetChainSegment,Cc as b2Shape_GetCircle,Xc as b2Shape_GetClosestPoint,Ec as b2Shape_GetContactCapacity,jc as b2Shape_GetContactData,lc as b2Shape_GetDensity,hc as b2Shape_GetFilter,bc as b2Shape_GetFriction,Gc as b2Shape_GetParentChain,Mc as b2Shape_GetPolygon,uc as b2Shape_GetRestitution,wc as b2Shape_GetSegment,Ac as b2Shape_GetType,sc as b2Shape_GetUserData,rc as b2Shape_IsSensor,zu as b2Shape_IsValid,ac as b2Shape_RayCast,Pc as b2Shape_SetCapsule,Dc as b2Shape_SetCircle,cc as b2Shape_SetDensity,mc as b2Shape_SetFilter,dc as b2Shape_SetFriction,Tc as b2Shape_SetPolygon,pc as b2Shape_SetRestitution,kc as b2Shape_SetSegment,nc as b2Shape_SetUserData,ic as b2Shape_TestPoint,Mn as b2Simplex,ah as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,bo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,vo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Yb as b2WeldJoint_GetAngularDampingRatio,qb as b2WeldJoint_GetAngularHertz,Fb as b2WeldJoint_GetLinearDampingRatio,Eb as b2WeldJoint_GetLinearHertz,Vb as b2WeldJoint_SetAngularDampingRatio,Xb as b2WeldJoint_SetAngularHertz,jb as b2WeldJoint_SetLinearDampingRatio,Lb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Nd as b2WheelJoint_EnableLimit,Kd as b2WheelJoint_EnableMotor,jd as b2WheelJoint_EnableSpring,Od as b2WheelJoint_GetLowerLimit,eb as b2WheelJoint_GetMaxMotorTorque,Qd as b2WheelJoint_GetMotorSpeed,Zd as b2WheelJoint_GetMotorTorque,Yd as b2WheelJoint_GetSpringDampingRatio,qd as b2WheelJoint_GetSpringHertz,Ud as b2WheelJoint_GetUpperLimit,Wd as b2WheelJoint_IsLimitEnabled,Hd as b2WheelJoint_IsMotorEnabled,Fd as b2WheelJoint_IsSpringEnabled,zd as b2WheelJoint_SetLimits,tb as b2WheelJoint_SetMaxMotorTorque,$d as b2WheelJoint_SetMotorSpeed,Vd as b2WheelJoint_SetSpringDampingRatio,Xd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,co as b2WorldId,p2 as b2World_CastCapsule,b2 as b2World_CastCircle,u2 as b2World_CastPolygon,c2 as b2World_CastRay,l2 as b2World_CastRayClosest,Vu as b2World_Draw,qh as b2World_DumpMemoryStats,Zu as b2World_EnableContinuous,$u as b2World_EnableSleeping,Qu as b2World_EnableWarmStarting,x2 as b2World_Explode,Yu as b2World_GetBodyEvents,Wu as b2World_GetContactEvents,Xh as b2World_GetCounters,f2 as b2World_GetGravity,Fh as b2World_GetProfile,Nu as b2World_GetSensorEvents,Ou as b2World_IsValid,n2 as b2World_OverlapAABB,i2 as b2World_OverlapCapsule,r2 as b2World_OverlapCircle,a2 as b2World_OverlapPolygon,o2 as b2World_SetContactTuning,m2 as b2World_SetCustomFilterCallback,y2 as b2World_SetGravity,e2 as b2World_SetHitEventThreshold,h2 as b2World_SetPreSolveCallback,t2 as b2World_SetRestitutionThreshold,Bi as b2World_Step,ch as b2Yield,Nh as mpx,Wh as pxm,or as pxmVec2}; +function Ye(t){let e=Yt(t);if(ee?t:e}function D2(t){return t<0?-t:t}function ht(t,e,o){return to?o:t}function P2(t,e){return te?t:e}function T2(t){return t<0?-t:t}function G2(t,e,o){return to?o:t}function j(t,e){return t.x*e.x+t.y*e.y}function z(t,e){return t.x*e.y-t.y*e.x}function Oo(t,e){return new g(e*t.y,-e*t.x)}function Gt(t,e){return new g(-t*e.y,t*e.x)}function de(t){return new g(-t.y,t.x)}function be(t){return new g(t.y,-t.x)}function U(t,e){return new g(t.x+e.x,t.y+e.y)}function J(t,e){return new g(t.x-e.x,t.y-e.y)}function Ht(t){return new g(-t.x,-t.y)}function $t(t,e,o){return new g((1-o)*t.x+o*e.x,(1-o)*t.y+o*e.y)}function R2(t,e){return new g(t.x*e.x,t.y*e.y)}function it(t,e){return new g(t*e.x,t*e.y)}function $(t,e,o){return new g(t.x+e*o.x,t.y+e*o.y)}function vi(t,e,o,n){n.x=t.x+e*o.x,n.y=t.y+e*o.y}function yt(t,e,o){return new g(t.x-e*o.x,t.y-e*o.y)}function Ma(t,e,o){let n=t.x-e.x,s=t.y-e.y;return n*o.x+s*o.y}function nr(t){return new g(Math.abs(t.x),Math.abs(t.y))}function Ji(t,e){return new g(Math.min(t.x,e.x),Math.min(t.y,e.y))}function Mi(t,e){return new g(Math.max(t.x,e.x),Math.max(t.y,e.y))}function L2(t,e,o){return new g(ht(t.x,e.x,o.x),ht(t.y,e.y,o.y))}function Yt(t){return Math.sqrt(t.x*t.x+t.y*t.y)}function Da(t,e){return Math.sqrt(t*t+e*e)}function pe(t){return t.x*t.x+t.y*t.y}function os(t,e){let o=e.x-t.x,n=e.y-t.y;return Math.sqrt(o*o+n*n)}function ue(t,e){let o=e.x-t.x,n=e.y-t.y;return o*o+n*n}function Di(t){return new rt(Math.cos(t),Math.sin(t))}function sr(t){let e=Math.sqrt(t.s*t.s+t.c*t.c),o=e>0?1/e:0;return new rt(t.c*o,t.s*o)}function E2(t,e){let o=Math.sqrt(e*e+t*t);return o>0?1/o:0}function wi(t){let e=t.s*t.s+t.c*t.c;return 1-6e-40?1/s:0;return new rt(o*r,n*r)}function F2(t,e,o){let n=t.c-e*t.s,s=t.s+e*t.c,r=Math.sqrt(s*s+n*n),i=r>0?1/r:0;o.c=n*i,o.s=s*i}function X2(t,e,o){return o*(e.s*t.c-e.c*t.s)}function q2(t){return Math.atan2(t.s,t.c)}function V2(t){return new g(t.c,t.s)}function Y2(t){return new g(-t.s,t.c)}function Pa(t,e){return new rt(t.c*e.c-t.s*e.s,t.s*e.c+t.c*e.s)}function N2(t,e){return t.c*e.c-t.s*e.s}function W2(t,e){return t.s*e.c+t.c*e.s}function O2(t,e){return new rt(t.c*e.c+t.s*e.s,t.c*e.s-t.s*e.c)}function oe(t,e){let o=t.s*e.c-t.c*e.s,n=t.c*e.c+t.s*e.s;return Math.atan2(o,n)}function vo(t){return t<-wo?t+2*wo:t>wo?t-2*wo:t}function K(t,e){return new g(t.c*e.x-t.s*e.y,t.s*e.x+t.c*e.y)}function Ie(t,e){return new g(t.c*e.x+t.s*e.y,-t.s*e.x+t.c*e.y)}function H(t,e){let o=t.q.c*e.x-t.q.s*e.y+t.p.x,n=t.q.s*e.x+t.q.c*e.y+t.p.y;return new g(o,n)}function Se(t,e,o){let n=t.q.c*e.x-t.q.s*e.y+t.p.x,s=t.q.s*e.x+t.q.c*e.y+t.p.y;o.x=n,o.y=s}function U2(t,e,o){o.p.x=t.q.c*e.x-t.q.s*e.y+t.p.x,o.p.y=t.q.s*e.x+t.q.c*e.y+t.p.y,o.q.c=t.q.c,o.q.s=t.q.s}function Re(t,e){let o=e.x-t.p.x,n=e.y-t.p.y;return new g(t.q.c*o+t.q.s*n,-t.q.s*o+t.q.c*n)}function z2(t,e){let o=new at;return o.q=Pa(t.q,e.q),o.p=U(K(t.q,e.p),t.p),o}function ki(t,e){let o=new at(new g,new rt);o.q.c=t.q.c*e.q.c+t.q.s*e.q.s,o.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let n=e.p.x-t.p.x,s=e.p.y-t.p.y;return o.p.x=t.q.c*n+t.q.s*s,o.p.y=-t.q.s*n+t.q.c*s,o}function Uo(t,e,o){let n=o;n.q.c=t.q.c*e.q.c+t.q.s*e.q.s,n.q.s=t.q.c*e.q.s-t.q.s*e.q.c;let s=e.p.x-t.p.x,r=e.p.y-t.p.y;n.p.x=t.q.c*s+t.q.s*r,n.p.y=-t.q.s*s+t.q.c*r}function ns(t,e){return new g(t.cx.x*e.x+t.cy.x*e.y,t.cx.y*e.x+t.cy.y*e.y)}function ss(t){let e=t.cx.x,o=t.cy.x,n=t.cx.y,s=t.cy.y,r=e*s-o*n;return r!==0&&(r=1/r),new ao(new g(r*s,-r*n),new g(-r*o,r*e))}function zo(t,e){let o=t.cx.x,n=t.cy.x,s=t.cx.y,r=t.cy.y,i=o*r-n*s;return i!==0&&(i=1/i),new g(i*(r*e.x-n*e.y),i*(o*e.y-s*e.x))}function Jo(t,e){return t.lowerBoundX<=e.lowerBoundX&&t.lowerBoundY<=e.lowerBoundY&&e.upperBoundX<=t.upperBoundX&&e.upperBoundY<=t.upperBoundY}function Le(t){return new g(.5*(t.lowerBoundX+t.upperBoundX),.5*(t.lowerBoundY+t.upperBoundY))}function rs(t){return new g(.5*(t.upperBoundX-t.lowerBoundX),.5*(t.upperBoundY-t.lowerBoundY))}function qt(t,e){let o=new xt;return o.lowerBoundX=Math.min(t.lowerBoundX,e.lowerBoundX),o.lowerBoundY=Math.min(t.lowerBoundY,e.lowerBoundY),o.upperBoundX=Math.max(t.upperBoundX,e.upperBoundX),o.upperBoundY=Math.max(t.upperBoundY,e.upperBoundY),o}function ae(t){return isFinite(t)&&!isNaN(t)}function rr(t){return t&&ae(t.x)&&ae(t.y)}function K2(t){return t&&ae(t.s)&&ae(t.c)&&wi(t)}function ka(t){if(!t)return!1;let e=t.upperBoundX-t.lowerBoundX,o=t.upperBoundY-t.lowerBoundY;return e>=0&&o>=0&&ae(t.lowerBoundX)&&ae(t.lowerBoundY)&&ae(t.upperBoundX)&&ae(t.upperBoundY)}function lt(t){let e=Yt(t);if(e>Xt){let o=1/e;return new g(t.x*o,t.y*o)}return new g(0,0)}function H2(t){let o=1/Yt(t);return new g(t.x*o,t.y*o)}var Ti=class{constructor(e=0,o=0,n=0){this.major=e,this.minor=o,this.revision=n}};var Q2=1,x=-1;function Ta(t){Q2=t}function Ga(){return Q2}function Ra(t){}function La(){return new Ti(3,1,0)}var We=1,De=1e5*We,te=2,It=.005*We;var Z2=.25*Math.PI,Qt=4*It,vn=.1*We,th=.5;function eh(){}function oh(){}function nh(){}function sh(){}function rh(){}function ih(t){}function ah(t){}function ch(){}var co=class{constructor(e=0,o=0){this.index1=e,this.revision=o}},Ee=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},St=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},zt=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}},Mo=class{constructor(e=0,o=0,n=0){this.index1=e,this.world0=o,this.revision=n}};function lh(t){return t.index1===0}function dh(t){return t.index1!==0}function bh(t,e){return t.index1===e.index1&&t.world0===e.world0&&t.revision===e.revision}var Ce=8;var Pn=4294967295,Po=class{constructor(){this.origin=null,this.translation=null,this.maxFraction=0}},Ko=class{constructor(){this.points=[],this.count=0,this.radius=0,this.translation=null,this.maxFraction=0}},me=class{constructor(e=null,o=null){this.normal=e,this.point=o,this.fraction=0,this.iterations=0,this.hit=!1}},je=class{constructor(){this.mass=0,this.center=null,this.rotationalInertia=0}},ce=class{constructor(e=null,o=0){this.center=e,this.center||(this.center=new g(0,0)),this.radius=o}},_e=class{constructor(){this.center1=null,this.center2=null,this.radius=0}},ge=class{constructor(e){e>0?(this.vertices=new Array(e).fill().map(()=>new g(0,0)),this.normals=new Array(e).fill().map(()=>new g(0,0))):(this.vertices=[],this.normals=[]),this.centroid=null,this.radius=0,this.count=0}},Oe=class{constructor(e=null,o=null){this.point1=e,this.point2=o}},Ue=class{constructor(){this.ghost1=null,this.segment=null,this.ghost2=null,this.chainId=0}},Jn=class{constructor(){this.points=[],this.count=0}},is=class{constructor(){this.closest1=null,this.closest2=null,this.fraction1=0,this.fraction2=0,this.distanceSquared=0}},Pe=class t{constructor(e=[],o=null,n=0){this.points=e,this.count=o,this.radius=n}clone(){let e=[];for(let o=0,n=this.points.length;ot0)return t.freeArray.pop();let e=t.nextIndex;return t.nextIndex++,e}function xe(t,e){if(e===t.nextIndex-1){t.nextIndex--;return}t.freeArray.push(e)}function on(t){return t.nextIndex-t.freeArray.length}function we(t,e){let o=new at;o.p=U(it(1-e,t.c1),it(e,t.c2));let n=new rt((1-e)*t.q1.c+e*t.q2.c,(1-e)*t.q1.s+e*t.q2.s);return o.q=sr(n),o.p=J(o.p,K(o.q,t.localCenter)),o}var xs=new is;function hr(t,e,o,n,s,r,i,c){let a=0,l=0,d=o-t,p=n-e,b=i-s,u=c-r,h=t-s,m=e-r,f=d*d+p*p,y=b*b+u*u,I=h*b+m*u,C=h*d+m*p;if(f=wn?(a=ht(-C/f,0,1),l=0):y>=wn&&(a=0,l=ht(I/y,0,1));else{let P=d*b+p*u,T=f*y-P*P,R=0;T!==0&&(R=ht((P*I-C*y)/T,0,1));let X=(P*R+I)/y;X<0?(X=0,R=ht(-C/f,0,1)):X>1&&(X=1,R=ht((P-C)/f,0,1)),a=R,l=X}let _=t+a*d,S=e+a*p,A=s+l*b,B=r+l*u,w=_-A,D=S-B,v=w*w+D*D;return xs.closest1=xs.closest2=null,xs.fraction1=a,xs.fraction2=l,xs.distanceSquared=v,xs}function vt(t,e,o){e=Math.min(e,Ce);let n=new Pe;n.points=[],n.count=e,n.radius=o;for(let s=0;sn&&(o=s,n=r)}return o}function pm(t,e,o,n,s){let r=new Mn;r.count=t.count;let i=[r.v1,r.v2,r.v3];for(let c=0;c0?de(e):be(e);default:return new g(0,0)}}function mm(t){switch(t.count){case 0:return new g(0,0);case 1:return t.v1.w;case 2:return ur(t.v1.a,t.v1.w,t.v2.a,t.v2.w);case 3:return new g(0,0);default:return new g(0,0)}}function hh(t,e,o){switch(o.count){case 0:break;case 1:t.x=o.v1.wA.x,t.y=o.v1.wA.y,e.x=o.v1.wB.x,e.y=o.v1.wB.y;break;case 2:t.x=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).x,t.y=ur(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA).y,e.x=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).x,e.y=ur(o.v1.a,o.v1.wB,o.v2.a,o.v2.wB).y;break;case 3:t.x=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).x,t.y=ph(o.v1.a,o.v1.wA,o.v2.a,o.v2.wA,o.v3.a,o.v3.wA).y,e.x=t.x,e.y=t.y;break;default:break}}function mh(t){let e=t.v1.w,o=t.v2.w,n=J(o,e),s=-j(e,n);if(s<=0){t.v1.a=1,t.count=1;return}let r=j(o,n);if(r<=0){t.v2.a=1,t.count=1,t.v1=t.v2;return}let i=1/(r+s);t.v1.a=r*i,t.v2.a=s*i,t.count=2}function yh(t){let e=t.v1.w,o=t.v2.w,n=t.v3.w,s=J(o,e),r=j(e,s),c=j(o,s),a=-r,l=J(n,e),d=j(e,l),b=j(n,l),u=-d,h=J(n,o),m=j(o,h),y=j(n,h),I=-m,C=z(s,l),_=C*z(o,n),S=C*z(n,e),A=C*z(e,o);if(a<=0&&u<=0){t.v1.a=1,t.count=1;return}if(c>0&&a>0&&A<=0){let w=1/(c+a);t.v1.a=c*w,t.v2.a=a*w,t.count=2;return}if(b>0&&u>0&&S<=0){let w=1/(b+u);t.v1.a=b*w,t.v3.a=u*w,t.count=2,t.v2=t.v3.clone();return}if(c<=0&&I<=0){t.v2.a=1,t.count=1,t.v1=t.v2.clone();return}if(b<=0&&y<=0){t.v3.a=1,t.count=1,t.v1=t.v3.clone();return}if(y>0&&I>0&&_<=0){let w=1/(y+I);t.v2.a=y*w,t.v3.a=I*w,t.count=2,t.v1=t.v3.clone();return}let B=1/(_+S+A);t.v1.a=_*B,t.v2.a=S*B,t.v3.a=A*B,t.count=3}var Is=new g;function Be(t,e,o,n){let s=new as,r=e.proxyA,i=e.proxyB,c=e.transformA,a=e.transformB,l=pm(t,r,c,i,a),d=0;o!==null&&dC+.5*I;){e.iterations+=1,u=yo(o,Ht(y)),h=o.points[u],m=yo(i,y),f=i.points[m];let v=J(h,f);y=lt(y);let P=j(y,v),T=j(y,a);if(P-C>l*T){if(T<=0||(l=(P-C)/T,l>d))return e;p.count=0}let R=b[p.count];switch(R.indexA=m,R.wA=new g(f.x+l*a.x,f.y+l*a.y),R.indexB=u,R.wB=h.clone(),R.w=J(R.wB,R.wA),R.a=1,p.count+=1,p.count){case 1:break;case 2:mh(p);break;case 3:yh(p);break;default:}if(p.count===3)return e;y=mm(p),++S}if(S===0||l===0)return e;let A=new g,B=new g;hh(B,A,p);let w=lt(Ht(y)),D=new g(A.x+o.radius*w.x,A.y+o.radius*w.y);return e.point=H(n,D),e.normal=K(n.q,w),e.fraction=l,e.iterations=S,e.hit=!0,e}var Eo={b2_pointsType:0,b2_faceAType:1,b2_faceBType:2},Ya=class{constructor(){this.proxyA=null,this.proxyB=null,this.sweepA=null,this.sweepB=null,this.localPoint=new g,this.axis=new g,this.type=0}};function xm(t,e,o,n,s,r){let i=new Ya;i.proxyA=e,i.proxyB=n;let c=t.count;i.sweepA=new bo,Object.assign(i.sweepA,o),i.sweepB=new bo,Object.assign(i.sweepB,s),i.localPoint=new g,i.axis=new g,i.type=0;let a=we(o,r),l=we(s,r);if(c===1){i.type=Eo.b2_pointsType;let y=e.points[t.indexA[0]],I=n.points[t.indexB[0]],C=H(a,y),_=H(l,I);return i.axis=lt(J(_,C)),i.localPoint=new g,i}if(t.indexA[0]===t.indexA[1]){i.type=Eo.b2_faceBType;let y=n.points[t.indexB[0]],I=n.points[t.indexB[1]];i.axis=Oo(J(I,y),1),i.axis=lt(i.axis);let C=K(l.q,i.axis);i.localPoint=new g(.5*(y.x+I.x),.5*(y.y+I.y));let _=H(l,i.localPoint),S=e.points[t.indexA[0]],A=H(a,S);return j(J(A,_),C)<0&&(i.axis=Ht(i.axis)),i}i.type=Eo.b2_faceAType;let d=e.points[t.indexA[0]],p=e.points[t.indexA[1]];i.axis=Oo(J(p,d),1),i.axis=lt(i.axis);let b=K(a.q,i.axis);i.localPoint=new g(.5*(d.x+p.x),.5*(d.y+p.y));let u=H(a,i.localPoint),h=n.points[t.indexB[0]],m=H(l,h);return j(J(m,u),b)<0&&(i.axis=Ht(i.axis)),i}var Ss=class{constructor(e,o,n){this.indexA=e,this.indexB=o,this.separation=n}};function Im(t,e){let o=we(t.sweepA,e),n=we(t.sweepB,e);switch(t.type){case Eo.b2_pointsType:{let s=Ie(o.q,t.axis),r=Ie(n.q,Ht(t.axis)),i=yo(t.proxyA,s),c=yo(t.proxyB,r),a=t.proxyA.points[i],l=t.proxyB.points[c],d=H(o,a),p=H(n,l),b=j(J(p,d),t.axis);return new Ss(i,c,b)}case Eo.b2_faceAType:{let s=K(o.q,t.axis),r=H(o,t.localPoint),i=Ie(n.q,Ht(s)),c=-1,a=yo(t.proxyB,i),l=t.proxyB.points[a],d=H(n,l),p=j(J(d,r),s);return new Ss(c,a,p)}case Eo.b2_faceBType:{let s=K(n.q,t.axis),r=H(n,t.localPoint),i=Ie(o.q,Ht(s)),c=-1,a=yo(t.proxyA,i),l=t.proxyA.points[a],d=H(o,l),p=j(J(d,r),s);return new Ss(a,c,p)}default:return new Ss(-1,-1,0)}}function uh(t,e,o,n){let s=we(t.sweepA,n),r=we(t.sweepB,n);switch(t.type){case Eo.b2_pointsType:{let i=t.proxyA.points[e],c=t.proxyB.points[o],a=H(s,i),l=H(r,c);return j(J(l,a),t.axis)}case Eo.b2_faceAType:{let i=K(s.q,t.axis),c=H(s,t.localPoint),a=t.proxyB.points[o],l=H(r,a);return j(J(l,c),i)}case Eo.b2_faceBType:{let i=K(r.q,t.axis),c=H(r,t.localPoint),a=t.proxyA.points[e],l=H(s,a);return j(J(l,c),i)}default:return 0}}function _s(t){let e=new ls;e.state=Go.b2_toiStateUnknown,e.t=t.tMax;let o=t.proxyA,n=t.proxyB,s=t.sweepA,r=t.sweepB,i=t.tMax,c=o.radius+n.radius,a=Math.max(It,c-It),l=.25*It,d=0,p=20,b=0,u=new ye,h=new he;for(h.proxyA=t.proxyA,h.proxyB=t.proxyB,h.useRadii=!1;;){let m=we(s,d),f=we(r,d);h.transformA=m,h.transformB=f;let y=Be(u,h,null,0);if(y.distance<=0){e.state=Go.b2_toiStateOverlapped,e.t=0;break}if(y.distancea+l){e.state=Go.b2_toiStateSeparated,e.t=i,C=!0;break}if(B>a-l){d=_;break}let v=uh(I,w,D,d);if(va?(T=X,v=F):(R=X,B=F),P==50)break}if(++S,S==Ce)break}if(++b,C)break;if(b==p){e.state=Go.b2_toiStateFailed,e.t=d;break}}return e}function Vi(t,e,o,n){let s=new Jn;if(n===0)return s;let r=lt(J(e,t)),i=[],c=0,a=0,l=z(J(o[a],t),r);l>0&&(i[c++]=o[a]);for(let u=1;ul&&(a=u,l=h),h>0&&(i[c++]=o[u])}if(l<2*It)return s;let d=o[a],p=Vi(t,d,i,c),b=Vi(d,e,i,c);for(let u=0;uCe)return o;let n=new xt(Number.MAX_VALUE,Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),s=[],r=0,i=16*It*It;for(let A=0;Al&&(a=A,l=B)}let d=s[a];s[a]=s[r-1],r=r-1;let p=0,b=ue(d,s[p]);for(let A=1;Ab&&(p=A,b=B)}let u=s[p];s[p]=s[r-1],r=r-1;let h=[],m=0,f=[],y=0,I=lt(J(u,d));for(let A=0;A=2*It?h[m++]=s[A]:B<=-2*It&&(f[y++]=s[A])}let C=Vi(d,u,h,m),_=Vi(u,d,f,y);if(C.count===0&&_.count===0)return o;o.points[o.count++]=d;for(let A=0;A2;){S=!1;for(let A=0;A=0)return!1}}for(let e=0;e0)for(let u=0;ub)return n;let u=Math.sqrt(b-d),h=a-u;if(h<0||t.maxFraction*i1){let T=new ce;return T.center=s,T.radius=e.radius,He(t,T)}return o}let m=new g(a.y,-a.x),f=Ye(d),y=f.length,I=f.normal,C=-a.x*I.y+I.x*a.y;if(-Xt0&&(b=Ht(b)),a.fraction=m,a.point=$(n,m,s),a.normal=b,a.hit=!0),a}function vs(t,e){if(e.radius===0){let n=t.origin,s=t.translation,r=0,i=t.maxFraction,c=-1,a=new me(fr,yr);for(let l=0;l0&&d=0&&(a.fraction=r,a.normal=e.normals[c],a.point=$(n,r,s),a.hit=!0),a}let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt([t.origin],1,0),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Ar(t,e){let o=new lo;return o.proxyA=vt([e.center.clone()],1,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Cr(t,e){let o=new lo;return o.proxyA=vt([e.center1,e.center2],2,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Js(t,e){let o=new lo;return o.proxyA=vt([e.point1,e.point2],2,0),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function wr(t,e){let o=new lo;return o.proxyA=vt(e.vertices,e.count,e.radius),o.proxyB=vt(t.points,t.count,t.radius),o.transformA=new at(new g(0,0),new rt(1,0)),o.transformB=new at(new g(0,0),new rt(1,0)),o.translationB=t.translation,o.maxFraction=t.maxFraction,jo(o)}function Bt(t,e){let o=e.index1-1;return t.shapeArray[o]}function Ih(t,e){let o=e.index1-1;return t.chainArray[o]}function Ua(t,e,o){let n=Qt,s=vn,r=Xo(t,e);r.lowerBoundX-=n,r.lowerBoundY-=n,r.upperBoundX+=n,r.upperBoundY+=n,t.aabb=r;let i=o==tt.b2_staticBody?n:s,c=new xt(r.lowerBoundX-i,r.lowerBoundY-i,r.upperBoundX+i,r.upperBoundY+i);t.fatAABB=c}function vr(t,e,o,n,s,r){let i=ne(t.shapeIdPool);i==t.shapeArray.length&&t.shapeArray.push(new Ni);let c=t.shapeArray[i];switch(r){case Y.b2_capsuleShape:c.capsule=s;break;case Y.b2_circleShape:c.circle=s;break;case Y.b2_polygonShape:c.polygon=s;break;case Y.b2_segmentShape:c.segment=s;break;case Y.b2_chainSegmentShape:c.chainSegment=s;break;default:break}if(c.id=i,c.bodyId=e.id,c.type=r,c.density=n.density,c.friction=n.friction,c.restitution=n.restitution,c.filter=n.filter,c.userData=n.userData,c.customColor=n.customColor,c.isSensor=n.isSensor,c.enlargedAABB=!1,c.enableSensorEvents=n.enableSensorEvents,c.enableContactEvents=n.enableContactEvents,c.enableHitEvents=n.enableHitEvents,c.enablePreSolveEvents=n.enablePreSolveEvents,c.isFast=!1,c.proxyKey=x,c.localCentroid=Ds(c),c.aabb=new xt,c.fatAABB=new xt,c.revision+=1,e.setIndex!=M.b2_disabledSet){let a=e.type;Vn(c,t.broadPhase,a,o,n.forceContactCreation||n.isSensor)}if(e.headShapeId!=x){let a=t.shapeArray[e.headShapeId];a.prevShapeId=i}return c.prevShapeId=x,c.nextShapeId=e.headShapeId,e.headShapeId=i,e.shapeCount+=1,Lt(t),c}function Jr(t,e,o,n){let s=ft(t.world0);if(s===null)return new St(0,0,0);let r=Z(s,t),i=Rt(s,r),c=vr(s,r,i,e,o,n);return r.updateBodyMass===!0&&cn(s,r),Lt(s),new St(c.id+1,t.world0,c.revision)}function Ms(t,e,o){return Jr(t,e,o,Y.b2_circleShape)}function qn(t,e,o){if(ue(o.center1,o.center2)<=It*It){let s=new ce;return s.center=$t(o.center1,o.center2,.5),s.radius=o.radius,Jr(t,e,s,Y.b2_circleShape)}return Jr(t,e,o,Y.b2_capsuleShape)}function fo(t,e,o){return Jr(t,e,o,Y.b2_polygonShape)}function za(t,e,o){return ue(o.point1,o.point2)<=It*It?new St:Jr(t,e,o,Y.b2_segmentShape)}function Sh(t,e,o,n){let s=e.id;e.prevShapeId!==x&&(t.shapeArray[e.prevShapeId].nextShapeId=e.nextShapeId),e.nextShapeId!==x&&(t.shapeArray[e.nextShapeId].prevShapeId=e.prevShapeId),s===o.headShapeId&&(o.headShapeId=e.nextShapeId),o.shapeCount-=1,an(e,t.broadPhase);let r=o.headContactKey;for(;r!==x;){let i=r>>1,c=r&1,a=t.contactArray[i];r=a.edges[c].nextKey,(a.shapeIdA===s||a.shapeIdB===s)&&xo(t,a,n)}xe(t.shapeIdPool,s),e.id=x,Lt(t)}function Ka(t){let e=ft(t.world0),o=t.index1-1,n=e.shapeArray[o],s=!0,r=_t(e,n.bodyId);Sh(e,n,r,s),r.updateBodyMass===!0&&cn(e,r)}function Ha(t,e){let o=ft(t.world0);if(o===null)return new Mo;let n=Z(o,t),s=Rt(o,n),r=ne(o.chainIdPool);r===o.chainArray.length&&o.chainArray.push(new Wi);let i=o.chainArray[r];i.id=r,i.bodyId=n.id,i.nextChainId=n.headChainId,i.revision+=1,n.headChainId=r;let c=fe();c.userData=e.userData,c.restitution=e.restitution,c.friction=e.friction,c.filter=e.filter,c.enableContactEvents=!1,c.enableHitEvents=!1,c.enableSensorEvents=!1;let a=e.count,l=e.points,d;if(e.isLoop){i.count=a,i.shapeIndices=new Array(a);let b=a-1;for(let h=0;h>1,l=i&1,d=t.contactArray[a];i=d.edges[l].nextKey,(d.shapeIdA===r||d.shapeIdB===r)&&xo(t,d,o)}let c=Rt(t,s);if(e.proxyKey!==x){let a=qo(e.proxyKey);if(Ua(e,c,a),n){zi(t.broadPhase,e.proxyKey);let l=!0;e.proxyKey=Ui(t.broadPhase,a,e.fatAABB,e.filter.categoryBits,r,l)}else Dr(t.broadPhase,e.proxyKey,e.fatAABB)}else{let a=s.type;Ua(e,c,a)}Lt(t)}function mc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);if(e.maskBits===n.filter.maskBits&&e.categoryBits===n.filter.categoryBits&&e.groupIndex===n.filter.groupIndex)return;let s=e.categoryBits===n.filter.categoryBits;n.filter=e,Mr(o,n,!0,s)}function yc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableSensorEvents=e}function fc(t){let e=O(t.world0);return Bt(e,t).enableSensorEvents}function xc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableContactEvents=e}function Ic(t){let e=O(t.world0);return Bt(e,t).enableContactEvents}function Sc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enablePreSolveEvents=e}function _c(t){let e=O(t.world0);return Bt(e,t).enablePreSolveEvents}function gc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.enableHitEvents=e}function Bc(t){let e=O(t.world0);return Bt(e,t).enableHitEvents}function Ac(t){let e=O(t.world0);return Bt(e,t).type}function Cc(t){let e=O(t.world0);return Bt(e,t).circle}function wc(t){let e=O(t.world0);return Bt(e,t).segment}function vc(t){let e=O(t.world0);return Bt(e,t).chainSegment}function Jc(t){let e=O(t.world0);return Bt(e,t).capsule}function Mc(t){let e=O(t.world0);return Bt(e,t).polygon}function Dc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.circle=e,n.type=Y.b2_circleShape,Mr(o,n,!0,!0)}function Pc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.capsule=e,n.type=Y.b2_capsuleShape,Mr(o,n,!0,!0)}function kc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.segment=e,n.type=Y.b2_segmentShape,Mr(o,n,!0,!0)}function Tc(t,e){let o=ft(t.world0);if(o===null)return;let n=Bt(o,t);n.polygon=e,n.type=Y.b2_polygonShape,Mr(o,n,!0,!0)}function Gc(t){let e=O(t.world0),o=Bt(e,t);if(o.type===Y.b2_chainSegmentShape){let n=o.chainSegment.chainId;if(n!==x){let s=e.chainArray[n];return new Mo(n+1,t.world0,s.revision)}}return new Mo}function Rc(t,e){let o=ft(t.world0);if(o===null)return;let n=Ih(o,t),s=n.count;for(let r=0;r>1,l=i&1,d=n.contactArray[a];if((d.shapeIdA===t.index1-1||d.shapeIdB===t.index1-1)&&d.flags&mt.b2_contactTouchingFlag){let p=n.shapeArray[d.shapeIdA],b=n.shapeArray[d.shapeIdB];e[c].shapeIdA=new St(p.id+1,t.world0,p.revision),e[c].shapeIdB=new St(b.id+1,t.world0,b.revision);let u=Yn(n,d);e[c].manifold=u.manifold,c+=1}i=d.edges[l].nextKey}return c}function Fc(t){let e=O(t.world0);return e===null?new xt:Bt(e,t).aabb}function Xc(t,e){let o=O(t.world0);if(o===null)return new g(0,0);let n=Bt(o,t),s=_t(o,n.bodyId),r=Rt(o,s),i=new he;i.proxyA=$e(n),i.proxyB=vt([e],1,0),i.transformA=r,i.transformB=new at(new g(0,0),new rt(1,0)),i.useRadii=!0;let c=new ye;return Be(c,i,null,0).pointA}var Ni=class{constructor(){this.id=0,this.bodyId=0,this.prevShapeId=0,this.nextShapeId=0,this.type=Y.e_unknown,this.density=0,this.friction=0,this.restitution=0,this.aabb=new xt,this.fatAABB=new xt,this.localCentroid=new g,this.proxyKey=0,this.filter=new ho,this.userData=null,this.customColor=0,this.capsule=new _e,this.circle=new ce,this.polygon=new ge,this.segment=new Oe,this.chainSegment=new Ue,this.revision=0,this.isSensor=!1,this.enableSensorEvents=!1,this.enableContactEvents=!1,this.enableHitEvents=!1,this.enablePreSolveEvents=!1,this.enlargedAABB=!1,this.isFast=!1,this.imageNoDebug=!1,this.image=null,this.imageScale=null,this.imageOffset=null,this.imageRect=null}},Wi=class{constructor(){this.id=0,this.bodyId=0,this.nextChainId=0,this.shapeIndices=[],this.count=0,this.revision=0}},Oi=class{constructor(){this.minExtent=0,this.maxExtent=0}};var Ki=8;function Qe(t){let e=new ke,o=Math.floor((t+Ki*8-1)/(Ki*8));return e.blockCapacity=o,e.blockCount=0,e.bits=new BigUint64Array(e.blockCapacity),e.bits.fill(0n),e}function Ze(t){t.blockCapacity=0,t.blockCount=0,t.bits=null}function to(t,e){let o=Math.floor((e+Ki*8-1)/(Ki*8));if(t.blockCapacity>1);t=Qe(n)}return t.blockCount=o,t.bits.fill(0n),t}function ks(t,e){let o=t.blockCount;for(let n=0;n=t.blockCount||(t.bits[o]&=~(BigInt(1)<=t.blockCount?!1:(t.bits[o]&BigInt(1)< 0");if(!(e.simFlags&Nt.b2_simTouchingFlag))throw new Error("Assert failed: contactSim.simFlags & b2_simTouchingFlag");if(!(o.flags&mt.b2_contactTouchingFlag))throw new Error("Assert failed: contact.flags & b2_contactTouchingFlag");let n=t.constraintGraph,s=Mt,r=o.edges[0].bodyId,i=o.edges[1].bodyId;se(t.bodyArray,r),se(t.bodyArray,i);let c=t.bodyArray[r],a=t.bodyArray[i],l=c.setIndex==M.b2_staticSet,d=a.setIndex==M.b2_staticSet;if(l&&d)throw new Error("Assert failed: staticA == false || staticB == false");let p=n.colors[s];o.colorIndex=s,o.localIndex=p.contacts.count;let b=Xe(p.contacts);if(b.set(e),l)b.bodySimIndexA=x,b.invMassA=0,b.invIA=0;else{if(c.setIndex!==M.b2_awakeSet)throw new Error("Assert failed: bodyA.setIndex == b2SetType.b2_awakeSet");let u=t.solverSetArray[M.b2_awakeSet],h=c.localIndex;if(!(0<=h&&h0?1/ct:0;let At=st*F-ot*X,Tt=L*F-nt*X,dt=S+v+A*At*At+P*Tt*Tt;et.tangentMass=dt>0?1/dt:0;let Et=I+-_*ot,Ft=C+_*st,Jt=B+-D*nt,Te=w+D*L;et.relativeVelocity=T*(Jt-Et)+R*(Te-Ft)}}}function Nc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states.data,c=new Pt;for(let a=0;a0?Q=N*a:e&&(Q=Math.max(et.biasRate*N,-l),wt=et.massScale,ct=et.impulseScale);let At=L.anchorAX,Tt=L.anchorAY,dt=L.anchorBX,Et=L.anchorBY,Ft=(B-I+D*-Et-_*-Tt)*R+(w-C+D*dt-_*At)*X,Jt=-L.normalMass*wt*(Ft+Q)-ct*L.normalImpulse,Te=Math.max(L.normalImpulse+Jt,0);Jt=Te-L.normalImpulse,L.normalImpulse=Te,L.maxNormalImpulse=Math.max(L.maxNormalImpulse,Jt);let Ge=Jt*R,ut=Jt*X;I-=u*Ge,C-=u*ut,_-=h*(At*ut-Tt*Ge),B+=m*Ge,w+=m*ut,D+=f*(dt*ut-Et*Ge)}for(let ot=0;otdt?dt:L.tangentImpulse,Tt=L.tangentImpulse-Et;let Ft=Tt*F,Jt=Tt*E;I-=u*Ft,C-=u*Jt,_-=h*(nt*Jt-Ct*Ft),B+=m*Ft,w+=m*Jt,D+=f*(N*Jt-Q*Ft)}y.linearVelocity.x=I,y.linearVelocity.y=C,y.angularVelocity=_,A.linearVelocity.x=B,A.linearVelocity.y=w,A.angularVelocity=D}}function Wc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts.count,i=t.world.solverSetArray[M.b2_awakeSet].states,c=t.world.restitutionThreshold,a=new Pt;for(let l=0;l-c||v.maxNormalImpulse===0)continue;let P=v.anchorAX,T=v.anchorAY,R=v.anchorBX,X=v.anchorBY,F=_.x+-S*X,E=_.y+S*R,W=y.x+-I*T,et=y.y+I*P,st=F-W,ot=E-et,L=st*A+ot*B,nt=-v.normalMass*(L+p*v.relativeVelocity),Ct=Math.max(v.normalImpulse+nt,0);nt=Ct-v.normalImpulse,v.normalImpulse=Ct,v.maxNormalImpulse=Math.max(v.maxNormalImpulse,nt);let N=nt*A,Q=nt*B;y.x-=b*N,y.y-=b*Q,I-=u*(P*Q-T*N),_.x+=h*N,_.y+=h*Q,S+=m*(R*Q-X*N)}f.angularVelocity=I,C.angularVelocity=S}}function Oc(t){let o=t.graph.colors[Mt],n=o.overflowConstraints,s=o.contacts,r=o.contacts.count;for(let i=0;i=e.upperBoundX||t.upperBoundX<=e.lowerBoundX||t.lowerBoundY>=e.upperBoundY||t.upperBoundY<=e.lowerBoundY)}var vm=1024;function Bh(t){return t.height===0}function Er(){let t=new hn;t.root=x,t.nodeCapacity=16,t.nodeCount=0,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn);for(let e=0;e>1,t.nodes=Array.from({length:t.nodeCapacity},()=>new Dn),t.nodes=Array.from({length:t.nodeCapacity},(s,r)=>r0;){let u=s[b].child1,h=s[b].child2,m=a+l;m1;){let n=Number.MAX_VALUE,s=-1,r=-1;for(let b=0;b0;){let i=r.pop();if(i==x)continue;let c=t.nodes[i];if(c.categoryBits&o&&pn(c.aabb,e))if(c.height==0){if(n(i,c.userData,s)===!1)return}else r.push(c.child1),r.push(c.child2)}}var ea=Array(64);function oa(t,e,o){if(t.root==x)return;let n=e.lowerBoundX,s=e.upperBoundX,r=e.lowerBoundY,i=e.upperBoundY,c=t.nodes,a=0;ea[a++]=t.root;let l,d,p;for(;a>0;)l=ea[--a],d=c[l],d.height==0?(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&sl(l,d.userData,o)):(p=d.aabb,p.lowerBoundXn&&p.lowerBoundYr&&(ea[a++]=d.child1,ea[a++]=d.child2))}function Gs(t,e,o,n,s){let r=e.origin,i=e.translation,c=lt(i),a=Gt(1,c),l=nr(a),d=e.maxFraction,p=$(r,d,i),b=new xt(Math.min(r.x,p.x),Math.min(r.y,p.y),Math.max(r.x,p.x),Math.max(r.y,p.y)),u=[];u.push(t.root);let h=e;for(;u.length>0;){let m=u.pop();if(m==x)continue;let f=t.nodes[m];if(pn(f.aabb,b)==!1||!(f.categoryBits&o))continue;let y=Le(f.aabb),I=rs(f.aabb),C=Math.abs(j(a,J(r,y)));if(!(j(l,I)0;){let f=m.pop();if(f==x)continue;let y=t.nodes[f];if(pn(y.aabb,u)==!1||!(y.categoryBits&o))continue;let I=Le(y.aabb),C=U(rs(y.aabb),c),_=Math.abs(j(l,J(i,I)));if(!(j(d,C)<_))if(y.height==0){h.maxFraction=p;let A=n(h,f,y.userData,s);if(A==0)return;0>1);let r=e[o].x,i=e[o].x,c=e[o].y,a=e[o].y;for(let h=o+1;hi&&(i=m),fa&&(a=f)}let l=i-r,d=a-c,p=l>d,b=o,u=n-1;if(p){let h=.5*(r+i);for(;;){for(;b<=u&&e[b].xh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}else{let h=.5*(c+a);for(;;){for(;b<=u&&e[b].yh;)u--;if(b>=u)break;let m=t[b];t[b]=t[u],t[u]=m,m=e[b],e[b]=e[u],e[u]=m,b++,u--}}return b>o&&b>1)}function Mm(t,e){let{nodes:o,leafIndices:n,leafCenters:s}=t;if(e===1)return o[n[0]].parent_next=x,n[0];let r=new Array(vm),i=0;for(r[0]={nodeIndex:Rr(t),childCount:-1,startIndex:0,endIndex:e,splitIndex:gh(n,s,0,e,e)};;){let d=r[i];if(d.childCount++,d.childCount===2){if(i===0)break;let p=r[i-1],b=o[p.nodeIndex],u=d.nodeIndex;p.childCount===0?b.child1=u:b.child2=u;let h=o[u];h.parent_next=p.nodeIndex;let m=o[h.child1],f=o[h.child2];h.aabb=qt(m.aabb,f.aabb),h.height=1+Math.max(m.height,f.height),h.categoryBits=m.categoryBits|f.categoryBits,i--}else{let[p,b]=d.childCount===0?[d.startIndex,d.splitIndex]:[d.splitIndex,d.endIndex],u=b-p;if(u===1){let h=n[p],m=o[d.nodeIndex];m[d.childCount===0?"child1":"child2"]=h,o[h].parent_next=d.nodeIndex}else r[++i]={nodeIndex:Rr(t),childCount:-1,startIndex:p,endIndex:b,splitIndex:gh(n,s,p,b,u)}}}let c=o[r[0].nodeIndex],a=o[c.child1],l=o[c.child2];return c.aabb=qt(a.aabb,l.aabb),c.height=1+Math.max(a.height,l.height),c.categoryBits=a.categoryBits|l.categoryBits,r[0].nodeIndex}function Rs(t){let e=t.proxyCount;if(e===0)return 0;if(e>t.rebuildCapacity){let l=e+Math.floor(e/2);t.leafIndices=Array(l),t.leafCenters=Array(l),t.rebuildCapacity=l}let o=0,n=[],s=t.root,r=t.nodes,i=r[s],c=t.leafIndices,a=t.leafCenters;for(;;){if(i.height===0||i.enlarged===!1)c[o]=s,a[o]=Le(i.aabb),o++,i.parent_next=x;else{let l=s;n.push(i.child2),s=i.child1,i=r[s],Lr(t,l);continue}if(n.length===0)break;s=n.pop(),i=r[s]}return t.root=Mm(t,o),o}function Ch(t,e){let o=t.nodes[e];return o?o.userData:0}var hn=class{constructor(){this.nodes=[],this.root=0,this.nodeCount=0,this.nodeCapacity=0,this.freeList=x,this.proxyCount=0,this.leafIndices=[],this.leafCenters=[],this.rebuildCapacity=0}};function Vr(t){if(t===0n)return 0;let e=Number(t&0xFFFFFFFFn);if(e!==0)return Math.clz32(e&-e)^31;{let o=Number(t>>32n);return Math.clz32(o&-o)^31|32}}var so=class{constructor(){this.sims=new Es,this.states=new Nr,this.joints=new dn,this.contacts=new ln,this.islands=new Wr,this.setIndex=0}};function Wn(t,e){let o=t.solverSetArray[e];o.sims=null,o.states=null,o.contacts=null,o.joints=null,o.islands=null,xe(t.solverSetIdPool,e),o=new so,o.setIndex=x,t.solverSetArray[e]=o}function qe(t,e){let o=t.solverSetArray[e],n=t.solverSetArray[M.b2_awakeSet],s=t.solverSetArray[M.b2_disabledSet],r=t.bodyArray,i=t.contactArray,c=o.sims.count;for(let u=0;u>1,S=i[_];if(I=S.edges[C].nextKey,S.setIndex!==M.b2_disabledSet)continue;let A=S.localIndex,B=s.contacts.data[A];if(S.setIndex=M.b2_awakeSet,S.localIndex=n.contacts.count,Xe(n.contacts).set(B),no(s.contacts,A)!==x){let P=s.contacts.data[A].contactId;i[P].localIndex=A}}}let a=o.contacts.count;for(let u=0;u0)return;let n=t.bodyMoveEventArray,s=ne(t.solverSetIdPool);if(s===t.solverSetArray.length){let y=new so;y.setIndex=x,t.solverSetArray.push(y)}let r=t.solverSetArray[M.b2_awakeSet],i=t.solverSetArray[s];i.setIndex=s,i.sims=il(o.bodyCount),i.contacts=al(o.contactCount),i.joints=cl(o.jointCount);let c=t.solverSetArray[M.b2_disabledSet],a=t.bodyArray,l=t.contactArray,d=o.headBody;for(;d!==x;){let y=a[d];y.bodyMoveIndex!==x&&(n[y.bodyMoveIndex].fellAsleep=!0,y.bodyMoveIndex=x);let I=y.localIndex,C=r.sims.data[I],_=i.sims.count,S=mn(i.sims);if(C.copyTo(S),Fs(r.sims,I)!==x){let D=r.sims.data[I].bodyId,v=a[D];v.localIndex=I}Xs(r.states,I),y.setIndex=s,y.localIndex=_;let B=y.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=l[w];if(B=v.edges[D].nextKey,v.setIndex===M.b2_disabledSet||v.colorIndex!==x)continue;let P=D^1,T=v.edges[P].bodyId;if(a[T].setIndex===M.b2_awakeSet)continue;let X=v.localIndex,F=r.contacts.data[X];if(v.setIndex=M.b2_disabledSet,v.localIndex=c.contacts.count,Xe(c.contacts).set(F),no(r.contacts,X)!==x){let st=r.contacts.data[X].contactId;l[st].localIndex=X}}d=y.islandNext}let p=o.headContact;for(;p!==x;){let y=l[p],I=y.colorIndex,C=t.constraintGraph.colors[I];I!==Mt&&(Io(C.bodySet,y.edges[0].bodyId),Io(C.bodySet,y.edges[1].bodyId));let _=y.localIndex,S=C.contacts.data[_],A=i.contacts.count;if(Xe(i.contacts).set(S),no(C.contacts,_)!==x){let v=C.contacts.data[_].contactId,P=l[v];P.localIndex=_}y.setIndex=s,y.colorIndex=x,y.localIndex=A,p=y.islandNext}let b=t.jointArray,u=o.headJoint;for(;u!==x;){let y=b[u],I=y.colorIndex,C=y.localIndex,_=t.constraintGraph.colors[I],S=_.joints.data[C];I!==Mt&&(Io(_.bodySet,y.edges[0].bodyId),Io(_.bodySet,y.edges[1].bodyId));let A=i.joints.count,B=oo(i.joints);if(S.copyTo(B),bn(_.joints,C)!==x){let v=_.joints.data[C].jointId,P=b[v];P.localIndex=C}y.setIndex=s,y.colorIndex=x,y.localIndex=A,u=y.islandNext}let h=o.localIndex,m=On(i.islands);if(m.islandId=e,Or(r.islands,h)!==x){let I=r.islands.data[h].islandId,C=t.islandArray[I];C.localIndex=h}o.setIndex=s,o.localIndex=0,Lt(t)}function rl(t,e,o){let n=t.solverSetArray[e],s=t.solverSetArray[o];n.sims.countl){let w=c/Math.sqrt(B);h.x*=w,h.y*=w,b.isSpeedCapped=!0}if(m*m>d&&b.allowFastRotation===!1){let w=a/Math.abs(m);m*=w,b.isSpeedCapped=!0}u.linearVelocity=h,u.angularVelocity=m}}function Pm(t,e,o){let n=o.states,s=o.h;for(let r=t;rW.sleepThreshold?(W.sleepTime=0,W.type===tt.b2_dynamicBody&&I&&R*d>.5*B.minExtent?(B.isBullet?(s.bulletBodyCount++,s.bulletBodies[s.bulletBodyCount-1]=S):(s.fastBodyCount++,s.fastBodies[s.fastBodyCount-1]=S),B.isFast=!0):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y)):(B.center0X=B.center.x,B.center0Y=B.center.y,B.rotation0.x=B.transform.q.x,B.rotation0.y=B.transform.q.y,W.sleepTime+=d);let et=h[W.islandId];if(W.sleepTime0&&W.sleepTime>y.splitSleepTime&&(y.splitIslandId=W.islandId,y.splitSleepTime=W.sleepTime);let st=B.transform,ot=B.isFast,L=W.headShapeId;for(;L!==x;){let nt=r.shapeArray[L];if(ot)nt.isFast=!0,eo(m,S);else{let Ct=Xo(nt,st);if(Ct.lowerBoundX-=C,Ct.lowerBoundY-=C,Ct.upperBoundX+=C,Ct.upperBoundY+=C,nt.aabb=Ct,Jo(nt.fatAABB,Ct)===!1){let N=new xt(Ct.lowerBoundX-_,Ct.lowerBoundY-_,Ct.upperBoundX+_,Ct.upperBoundY+_);nt.fatAABB=N,nt.enlargedAABB=!0,eo(m,S)}}L=nt.nextShapeId}}}function Tm(t,e,o){let n=t.type,s=o.startIndex,r=s+o.count;n===yn.b2_stageIntegrateVelocities?Dm(s,r,e):n===yn.b2_stageIntegratePositions&&Pm(s,r,e)}function Vo(t,e){let o=t.blockCount;for(let n=0;n0)return!0}let u=new cs;u.proxyA=$e(c),u.proxyB=$e(s),u.sweepA=ra(d,Rm),u.sweepB=n.sweep,u.tMax=n.fraction;let h=n.fraction,m=!1,f=_s(u);if(00?1:0,c+=wt}{let N=t.bodyMoveEventArray;for(;N.lengthb*p?(b=Math.floor(n/p),u=p):u=Math.floor(n-1>>5)+1;let h=new Array(te),m=new Array(te),f=new Array(te),y=new Array(te),I=new Array(te),C=new Array(te),_=0,S=0,A=i[Mt].contacts.count,B=ze(t.stackAllocator,A,"overflow contact constraint",()=>new Gr);r.colors[Mt].overflowConstraints=B;let w=d,D=S>0?Math.floor(S-1>>2)+1:0;S>w*p&&(w=Math.floor(S/p),D=p);let v=d,P=c>0?Math.floor(c-1>>2)+1:0;c>v*p&&(v=Math.floor(c/p),P=p);let T=0;T+=1,T+=1,T+=1,T+=a,T+=a,T+=1,T+=a,T+=a,T+=1;let R=Array.from({length:T},()=>new na),X=ze(t.stackAllocator,u,"body blocks"),F=ze(t.stackAllocator,D,"contact blocks"),E=ze(t.stackAllocator,P,"joint blocks"),W=ze(t.stackAllocator,_,"graph blocks");t.splitIslandId!=x&&Ur(t,t.splitIslandId);for(let N=0;N0&&(E[P-1].count=c-(P-1)*v);for(let N=0;N0&&(F[D-1].count=S-(D-1)*w);let et=new Array(te),st=0;for(let N=0;N0&&(W[st+Q-1].count=y[N]-(Q-1)*wt,st+=Q);let ct=f[N],At=m[N];for(let Tt=0;Tt0&&(W[st+ct-1].count=h[N]-(ct-1)*At,st+=ct)}let ot=st,L=0,nt=(N,Q,wt,ct,At=-1)=>{N.type=Q,N.blocks=wt,N.blockCount=ct,N.colorIndex=At,N.completionCount=0};nt(R[L++],yn.b2_stagePrepareJoints,E,P),nt(R[L++],yn.b2_stagePrepareContacts,F,D),nt(R[L++],yn.b2_stageIntegrateVelocities,X,u),nt(R[L++],yn.b2_stageIntegratePositions,X,u),nt(R[L++],yn.b2_stageStoreImpulses,F,D),e.graph=r,e.joints=null,e.contacts=null,e.simdContactConstraints=null,e.activeColorCount=a,e.workerCount=l,e.stageCount=T,e.stages=R;{let N=new bl;N.context=e,N.workerIndex=0,Gm(N)}t.splitIslandId=x;let Ct=o.islands.count;for(let N=0;Nu.approachSpeed&&y.maxNormalImpulse>0&&(u.approachSpeed=I,u.pointX=y.pointX,u.pointY=y.pointY,h=!0)}if(h===!0){u.normalX=b.manifold.normalX,u.normalY=b.manifold.normalY;let f=t.shapeArray[b.shapeIdA],y=t.shapeArray[b.shapeIdB];u.shapeIdA=new St(f.id+1,t.worldId,f.revision),u.shapeIdB=new St(y.id+1,t.worldId,y.revision),t.contactHitArray.push(u)}}}}let s=t.taskContextArray[0].enlargedSimBitSet;for(let r=1;r0&&Em(0,e.fastBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.fastBodies,d=e.fastBodyCount;for(let p=0;p0&&jm(0,e.bulletBodyCount,e);{let i=t.broadPhase.trees[tt.b2_dynamicBody],c=t.bodyArray,a=t.shapeArray,l=e.bulletBodies,d=e.bulletBodyCount;for(let p=0;pr&&(t.splitIslandId=d.splitIslandId,r=d.splitSleepTime)}let i=t.taskContextArray[0].awakeIslandBitSet;for(let l=1;l=0;l-=1){if(_h(i,l)===!0)continue;let p=c[l].islandId;Yr(t,p)}Lt(t)}}function fl(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.length=ht(e,It,De),n.impulse=0,n.lowerImpulse=0,n.upperImpulse=0}function xl(t){return q(t,k.b2_distanceJoint).distanceJoint.length}function Il(t,e){let n=q(t,k.b2_distanceJoint).distanceJoint;n.enableLimit=e}function Sl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableLimit}function _l(t,e,o){let s=q(t,k.b2_distanceJoint).distanceJoint;e=ht(e,It,De),o=ht(o,It,De),s.minLength=Math.min(e,o),s.maxLength=Math.max(e,o),s.impulse=0,s.lowerImpulse=0,s.upperImpulse=0}function gl(t){return q(t,k.b2_distanceJoint).distanceJoint.minLength}function Bl(t){return q(t,k.b2_distanceJoint).distanceJoint.maxLength}function Al(t){let e=q(t,k.b2_distanceJoint),o=O(t.world0);if(o.locked)return 0;let n=le(o,e.bodyIdA),s=le(o,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r);return Yt(c)}function Cl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.enableSpring=e}function wl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableSpring}function vl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.hertz=e}function Jl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.dampingRatio=e}function Ml(t){return q(t,k.b2_distanceJoint).distanceJoint.hertz}function Dl(t){return q(t,k.b2_distanceJoint).distanceJoint.dampingRatio}function Pl(t,e){let o=q(t,k.b2_distanceJoint);e!==o.distanceJoint.enableMotor&&(o.distanceJoint.enableMotor=e,o.distanceJoint.motorImpulse=0)}function kl(t){return q(t,k.b2_distanceJoint).distanceJoint.enableMotor}function Tl(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.motorSpeed=e}function Gl(t){return q(t,k.b2_distanceJoint).distanceJoint.motorSpeed}function Rl(t){let e=O(t.world0),o=q(t,k.b2_distanceJoint);return e.inv_h*o.distanceJoint.motorImpulse}function Ll(t,e){let o=q(t,k.b2_distanceJoint);o.distanceJoint.maxMotorForce=e}function El(t){return q(t,k.b2_distanceJoint).distanceJoint.maxMotorForce}function jl(t,e){let o=e.distanceJoint,n=le(t,e.bodyIdA),s=le(t,e.bodyIdB),r=H(n,e.localOriginAnchorA),i=H(s,e.localOriginAnchorB),c=J(i,r),a=lt(c),l=(o.impulse+o.lowerImpulse-o.upperImpulse+o.motorImpulse)*t.inv_h;return it(l,a)}function Fl(t,e){let o=e.world,n=o.bodyArray,s=t.bodyIdA,r=t.bodyIdB,i=n[s],c=n[r],a=o.solverSetArray[i.setIndex],l=o.solverSetArray[c.setIndex],d=a.sims.data[i.localIndex],p=l.sims.data[c.localIndex],b=d.invMass,u=d.invInertia,h=p.invMass,m=p.invInertia;t.invMassA=b,t.invMassB=h,t.invIA=u,t.invIB=m;let f=t.distanceJoint;f.indexA=i.setIndex===M.b2_awakeSet?i.localIndex:x,f.indexB=c.setIndex===M.b2_awakeSet?c.localIndex:x,f.anchorA=K(d.transform.q,J(t.localOriginAnchorA,d.localCenter)),f.anchorB=K(p.transform.q,J(t.localOriginAnchorB,p.localCenter)),f.deltaCenter=J(p.center,d.center);let y=f.anchorA,I=f.anchorB,C=U(J(I,y),f.deltaCenter),_=lt(C),S=z(y,_),A=z(I,_),B=b+h+u*S*S+m*A*A;f.axialMass=B>0?1/B:0,f.distanceSoftness=ie(f.hertz,f.dampingRatio,e.h),e.enableWarmStarting===!1&&(f.impulse=0,f.lowerImpulse=0,f.upperImpulse=0,f.motorImpulse=0)}function Xl(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.distanceJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(J(l.deltaPosition,a.deltaPosition),J(p,d)),u=U(c.deltaCenter,b),h=lt(u),m=c.impulse+c.lowerImpulse-c.upperImpulse+c.motorImpulse,f=it(m,h);a.linearVelocity=yt(a.linearVelocity,o,f),a.angularVelocity-=s*z(d,f),l.linearVelocity=$(l.linearVelocity,n,f),l.angularVelocity+=r*z(p,f)}function ql(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.distanceJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=Yt(I),_=lt(I);if(a.enableSpring&&(a.minLength0){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=a.distanceSoftness.biasRate*B,v=-(a.distanceSoftness.massScale*a.axialMass)*(A+w)-a.distanceSoftness.impulseScale*a.impulse;a.impulse+=v;let P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}if(a.enableLimit){{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.minLength,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.lowerImpulse,T=Math.max(0,a.lowerImpulse+P),R=T-a.lowerImpulse;a.lowerImpulse=T;let X=it(R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}{let S=U(J(p,u),J(Gt(b,m),Gt(h,f))),A=j(_,S),B=a.maxLength-C,w=0,D=1,v=0;B>0?w=B*e.inv_h:o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.upperImpulse,T=Math.max(0,a.upperImpulse+P),R=T-a.upperImpulse;a.upperImpulse=T;let X=it(-R,_);p=yt(p,n,X),b-=r*z(m,X),u=$(u,s,X),h+=i*z(f,X)}}if(a.enableMotor){let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D);let v=a.motorImpulse-w,P=it(v,_);p=yt(p,n,P),b-=r*z(m,P),u=$(u,s,P),h+=i*z(f,P)}}else{let S=U(J(u,p),J(Gt(h,f),Gt(b,m))),A=j(_,S),B=C-a.length,w=0,D=1,v=0;o&&(w=e.jointSoftness.biasRate*B,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale);let P=-D*a.axialMass*(A+w)-v*a.impulse;a.impulse+=P;let T=it(P,_);p=yt(p,n,T),b-=r*z(m,T),u=$(u,s,T),h+=i*z(f,T)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Vl(t,e,o,n){let s=e.distanceJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=lt(J(i,r));if(s.minLengthIt&&t.DrawSegment(J(a,d),U(a,d),V.b2_colorLightGreen,t.context),s.maxLengthIt&&s.maxLength0&&s.enableSpring){let a=$(r,s.length,c);t.DrawPoint(a.x,a.y,4,V.b2_colorBlue,t.context)}}function Yl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableSpring&&(o.prismaticJoint.enableSpring=e,o.prismaticJoint.springImpulse=0)}function Nl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableSpring}function Wl(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.hertz=e}function Ol(t){return q(t,k.b2_prismaticJoint).prismaticJoint.hertz}function Ul(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.dampingRatio=e}function zl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.dampingRatio}function Kl(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableLimit&&(o.prismaticJoint.enableLimit=e,o.prismaticJoint.lowerImpulse=0,o.prismaticJoint.upperImpulse=0)}function Hl(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableLimit}function $l(t){return q(t,k.b2_prismaticJoint).prismaticJoint.lowerTranslation}function Ql(t){return q(t,k.b2_prismaticJoint).prismaticJoint.upperTranslation}function Zl(t,e,o){let n=q(t,k.b2_prismaticJoint);(e!==n.prismaticJoint.lowerTranslation||o!==n.prismaticJoint.upperTranslation)&&(n.prismaticJoint.lowerTranslation=Math.min(e,o),n.prismaticJoint.upperTranslation=Math.max(e,o),n.prismaticJoint.lowerImpulse=0,n.prismaticJoint.upperImpulse=0)}function td(t,e){let o=q(t,k.b2_prismaticJoint);e!==o.prismaticJoint.enableMotor&&(o.prismaticJoint.enableMotor=e,o.prismaticJoint.motorImpulse=0)}function ed(t){return q(t,k.b2_prismaticJoint).prismaticJoint.enableMotor}function od(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.motorSpeed=e}function nd(t){return q(t,k.b2_prismaticJoint).prismaticJoint.motorSpeed}function sd(t){let e=O(t.world0),o=q(t,k.b2_prismaticJoint);return e.inv_h*o.prismaticJoint.motorImpulse}function rd(t,e){let o=q(t,k.b2_prismaticJoint);o.prismaticJoint.maxMotorForce=e}function id(t){return q(t,k.b2_prismaticJoint).prismaticJoint.maxMotorForce}function ad(t,e){let o=e.bodyIdA,n=le(t,o),s=e.prismaticJoint,r=K(n.q,s.localAxisA),i=de(r),c=t.inv_h,a=c*s.impulse.x,l=c*(s.motorImpulse+s.lowerImpulse-s.upperImpulse);return U(it(a,i),it(l,r))}function cd(t,e){return t.inv_h*e.prismaticJoint.impulse.y}function ld(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.prismaticJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=z(U(B,S),I.axisA),D=z(A,I.axisA),v=h+f+m*w*w+y*D*D;I.axialMass=v>0?1/v:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting==!1&&(I.impulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function dd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.prismaticJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=z(U(b,d),u),m=z(p,u),f=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse,y=de(u),I=z(U(b,d),y),C=z(p,y),_=c.impulse.x,S=c.impulse.y,A=U(it(f,u),it(_,y)),B=f*h+_*I+S,w=f*m+_*C+S;a.linearVelocity=yt(a.linearVelocity,o,A),a.angularVelocity-=s*B,l.linearVelocity=$(l.linearVelocity,n,A),l.angularVelocity+=r*w}function bd(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.prismaticJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(f,m)),I=K(l.deltaRotation,a.axisA),C=j(I,y),_=z(U(y,m),I),S=z(f,I);if(a.enableSpring){let A=C,B=a.springSoftness.biasRate*A,w=a.springSoftness.massScale,D=a.springSoftness.impulseScale,v=j(I,J(u,p))+S*h-_*b,P=-w*a.axialMass*(v+B)-D*a.springImpulse;a.springImpulse+=P;let T=it(P,I),R=P*_,X=P*S;p=yt(p,n,T),b-=r*R,u=$(u,s,T),h+=i*X}if(a.enableMotor){let A=j(I,J(u,p))+S*h-_*b,B=a.axialMass*(a.motorSpeed-A),w=a.motorImpulse,D=e.h*a.maxMotorForce;a.motorImpulse=ht(a.motorImpulse+B,-D,D),B=a.motorImpulse-w;let v=it(B,I),P=B*_,T=B*S;p=yt(p,n,v),b-=r*P,u=$(u,s,v),h+=i*T}if(a.enableLimit){{let A=C-a.lowerTranslation,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.lowerImpulse,P=j(I,J(u,p))+S*h-_*b,T=-a.axialMass*w*(P+B)-D*v;a.lowerImpulse=Math.max(v+T,0),T=a.lowerImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}{let A=a.upperTranslation-C,B=0,w=1,D=0;A>0?B=A*e.inv_h:o&&(B=e.jointSoftness.biasRate*A,w=e.jointSoftness.massScale,D=e.jointSoftness.impulseScale);let v=a.upperImpulse,P=j(I,J(p,u))+_*b-S*h,T=-a.axialMass*w*(P+B)-D*v;a.upperImpulse=Math.max(v+T,0),T=a.upperImpulse-v;let R=it(T,I),X=T*_,F=T*S;p=$(p,n,R),b+=r*X,u=yt(u,s,R),h-=i*F}}{let A=de(I),B=z(U(y,m),A),w=z(f,A),D=new g(j(A,J(u,p))+w*h-B*b,h-b),v=new g,P=1,T=0;if(o){let nt=new g(j(A,y),oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle);v=it(e.jointSoftness.biasRate,nt),P=e.jointSoftness.massScale,T=e.jointSoftness.impulseScale}let R=n+s+r*B*B+i*w*w,X=r*B+i*w,F=r+i;F===0&&(F=1);let E=new ao(new g(R,X),new g(X,F)),W=zo(E,U(D,v)),et=new g(-P*W.x-T*a.impulse.x,-P*W.y-T*a.impulse.y);a.impulse.x+=et.x,a.impulse.y+=et.y;let st=it(et.x,A),ot=et.x*B+et.y,L=et.x*w+et.y;p=yt(p,n,st),b-=r*ot,u=$(u,s,st),h+=i*L}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function pd(t,e,o,n){let s=e.prismaticJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorBlue,b=V.b2_colorGray4;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function ud(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableSpring&&(o.revoluteJoint.enableSpring=e,o.revoluteJoint.springImpulse=0)}function hd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableSpring}function md(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.hertz=e}function yd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.hertz}function fd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.dampingRatio=e}function xd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.dampingRatio}function Id(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint),n=le(e,o.bodyIdA),s=le(e,o.bodyIdB),r=oe(s.q,n.q)-o.revoluteJoint.referenceAngle;return r=vo(r),r}function Sd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableLimit&&(o.revoluteJoint.enableLimit=e,o.revoluteJoint.lowerImpulse=0,o.revoluteJoint.upperImpulse=0)}function _d(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableLimit}function gd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.lowerAngle}function Bd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.upperAngle}function Ad(t,e,o){let n=q(t,k.b2_revoluteJoint);(e!==n.revoluteJoint.lowerAngle||o!==n.revoluteJoint.upperAngle)&&(n.revoluteJoint.lowerAngle=Math.min(e,o),n.revoluteJoint.upperAngle=Math.max(e,o),n.revoluteJoint.lowerImpulse=0,n.revoluteJoint.upperImpulse=0)}function Cd(t,e){let o=q(t,k.b2_revoluteJoint);e!==o.revoluteJoint.enableMotor&&(o.revoluteJoint.enableMotor=e,o.revoluteJoint.motorImpulse=0)}function wd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.enableMotor}function vd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.motorSpeed=e}function Jd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.motorSpeed}function Md(t){let e=O(t.world0),o=q(t,k.b2_revoluteJoint);return e.inv_h*o.revoluteJoint.motorImpulse}function Dd(t,e){let o=q(t,k.b2_revoluteJoint);o.revoluteJoint.maxMotorTorque=e}function Pd(t){return q(t,k.b2_revoluteJoint).revoluteJoint.maxMotorTorque}function kd(t,e){return it(t.inv_h,e.revoluteJoint.linearImpulse)}function Td(t,e){let o=e.revoluteJoint;return t.inv_h*(o.motorImpulse+o.lowerImpulse-o.upperImpulse)}function Gd(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.revoluteJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.referenceAngle,I.deltaAngle=vo(I.deltaAngle);let C=m+y;I.axialMass=C>0?1/C:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function Rd(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.revoluteJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=c.springImpulse+c.motorImpulse+c.lowerImpulse-c.upperImpulse;a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+b),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+b)}function Ld(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.revoluteJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity.clone(),b=l.angularVelocity,u=d.linearVelocity.clone(),h=d.angularVelocity,m=r+i===0;if(a.enableSpring&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle,y=a.springSoftness.biasRate*f,I=a.springSoftness.massScale,C=a.springSoftness.impulseScale,_=h-b,S=-I*a.axialMass*(_+y)-C*a.springImpulse;a.springImpulse+=S,b-=r*S,h+=i*S}if(a.enableMotor&&m===!1){let f=h-b-a.motorSpeed,y=-a.axialMass*f,I=a.motorImpulse,C=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+y,-C,C),y=a.motorImpulse-I,b-=r*y,h+=i*y}if(a.enableLimit&&m===!1){let f=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;f=vo(f);{let y=f-a.lowerAngle,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=h-b,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.lowerImpulse;a.lowerImpulse=Math.max(a.lowerImpulse+A,0),A=a.lowerImpulse-B,b-=r*A,h+=i*A}{let y=a.upperAngle-f,I=0,C=1,_=0;y>0?I=y*e.inv_h:o&&(I=e.jointSoftness.biasRate*y,C=e.jointSoftness.massScale,_=e.jointSoftness.impulseScale);let S=b-h,A=-C*a.axialMass*(S+I)-_*a.lowerImpulse,B=a.upperImpulse;a.upperImpulse=Math.max(a.upperImpulse+A,0),A=a.upperImpulse-B,b+=r*A,h-=i*A}}{let f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=J(U(u,Gt(h,y)),U(p,Gt(b,f))),C=new g(0,0),_=1,S=0;if(o){let D=l.deltaPosition,v=d.deltaPosition,P=U(U(J(v,D),J(y,f)),a.deltaCenter);C=it(e.jointSoftness.biasRate,P),_=e.jointSoftness.massScale,S=e.jointSoftness.impulseScale}let A={cx:new g(0,0),cy:new g(0,0)};A.cx.x=n+s+f.y*f.y*r+y.y*y.y*i,A.cy.x=-f.y*f.x*r-y.y*y.x*i,A.cx.y=A.cy.x,A.cy.y=n+s+f.x*f.x*r+y.x*y.x*i;let B=zo(A,U(I,C)),w=new g(-_*B.x-S*a.linearImpulse.x,-_*B.y-S*a.linearImpulse.y);a.linearImpulse.x+=w.x,a.linearImpulse.y+=w.y,p=yt(p,n,w),b-=r*z(f,w),u=$(u,s,w),h+=i*z(y,w)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Ed(t,e,o,n,s){let r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=V.b2_colorRed,a=s;t.DrawCircle(i,a,c,t.context);let l=oe(n.q,o.q),d=new g(a*Math.cos(l),a*Math.sin(l)),p=U(i,d);t.DrawSegment(i,p,c,t.context);let b=V.b2_colorGold;t.DrawSegment(o.p,r,b,t.context),t.DrawSegment(r,i,b,t.context),t.DrawSegment(n.p,i,b,t.context)}function jd(t,e){let o=q(t,k.b2_wheelJoint);e!==o.wheelJoint.enableSpring&&(o.wheelJoint.enableSpring=e,o.wheelJoint.springImpulse=0)}function Fd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableSpring}function Xd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.hertz=e}function qd(t){return q(t,k.b2_wheelJoint).wheelJoint.hertz}function Vd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.dampingRatio=e}function Yd(t){return q(t,k.b2_wheelJoint).wheelJoint.dampingRatio}function Nd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableLimit!==e&&(o.wheelJoint.lowerImpulse=0,o.wheelJoint.upperImpulse=0,o.wheelJoint.enableLimit=e)}function Wd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableLimit}function Od(t){return q(t,k.b2_wheelJoint).wheelJoint.lowerTranslation}function Ud(t){return q(t,k.b2_wheelJoint).wheelJoint.upperTranslation}function zd(t,e,o){let n=q(t,k.b2_wheelJoint);(e!==n.wheelJoint.lowerTranslation||o!==n.wheelJoint.upperTranslation)&&(n.wheelJoint.lowerTranslation=Math.min(e,o),n.wheelJoint.upperTranslation=Math.max(e,o),n.wheelJoint.lowerImpulse=0,n.wheelJoint.upperImpulse=0)}function Kd(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.enableMotor!==e&&(o.wheelJoint.motorImpulse=0,o.wheelJoint.enableMotor=e)}function Hd(t){return q(t,k.b2_wheelJoint).wheelJoint.enableMotor}function $d(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.motorSpeed=e}function Qd(t){return q(t,k.b2_wheelJoint).wheelJoint.motorSpeed}function Zd(t){let e=O(t.world0),o=q(t,k.b2_wheelJoint);return e.inv_h*o.wheelJoint.motorImpulse}function tb(t,e){let o=q(t,k.b2_wheelJoint);o.wheelJoint.maxMotorTorque=e}function eb(t){return q(t,k.b2_wheelJoint).wheelJoint.maxMotorTorque}function ob(t,e){let o=e.wheelJoint,n=o.axisA,s=de(n),r=t.inv_h*o.perpImpulse,i=t.inv_h*(o.springImpulse+o.lowerImpulse-o.upperImpulse);return U(it(r,s),it(i,n))}function nb(t,e){return t.inv_h*e.wheelJoint.motorImpulse}function sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.wheelJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.axisA=K(C,I.localAxisA),I.deltaCenter=J(u.center,b.center);let S=I.anchorA,A=I.anchorB,B=U(I.deltaCenter,J(A,S)),w=I.axisA,D=de(w),v=z(U(B,S),D),P=z(A,D),T=h+f+m*v*v+y*P*P;I.perpMass=T>0?1/T:0;let R=z(U(B,S),w),X=z(A,w),F=h+f+m*R*R+y*X*X;I.axialMass=F>0?1/F:0,I.springSoftness=ie(I.hertz,I.dampingRatio,e.h);let E=m+y;I.motorMass=E>0?1/E:0,e.enableWarmStarting==!1&&(I.perpImpulse=0,I.springImpulse=0,I.motorImpulse=0,I.lowerImpulse=0,I.upperImpulse=0)}function rb(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.wheelJoint,a=c.indexA==x?i:e.states[c.indexA],l=c.indexB==x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB),b=U(U(J(l.deltaPosition,a.deltaPosition),c.deltaCenter),J(p,d)),u=K(a.deltaRotation,c.axisA),h=de(u),m=z(U(b,d),u),f=z(p,u),y=z(U(b,d),h),I=z(p,h),C=c.springImpulse+c.lowerImpulse-c.upperImpulse,_=U(it(C,u),it(c.perpImpulse,h)),S=C*m+c.perpImpulse*y+c.motorImpulse,A=C*f+c.perpImpulse*I+c.motorImpulse;a.linearVelocity=yt(a.linearVelocity,o,_),a.angularVelocity-=s*S,l.linearVelocity=$(l.linearVelocity,n,_),l.angularVelocity+=r*A}function ib(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.wheelJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity,m=r+i===0,f=K(l.deltaRotation,a.anchorA),y=K(d.deltaRotation,a.anchorB),I=U(U(J(d.deltaPosition,l.deltaPosition),a.deltaCenter),J(y,f)),C=K(l.deltaRotation,a.axisA),_=j(C,I),S=z(U(I,f),C),A=z(y,C);if(a.enableMotor&&m===!1){let B=h-b-a.motorSpeed,w=-a.motorMass*B,D=a.motorImpulse,v=e.h*a.maxMotorTorque;a.motorImpulse=ht(a.motorImpulse+w,-v,v),w=a.motorImpulse-D,b-=r*w,h+=i*w}if(a.enableSpring){let B=_,w=a.springSoftness.biasRate*B,D=a.springSoftness.massScale,v=a.springSoftness.impulseScale,P=j(C,J(u,p))+A*h-S*b,T=-D*a.axialMass*(P+w)-v*a.springImpulse;a.springImpulse+=T;let R=it(T,C),X=T*S,F=T*A;p=yt(p,n,R),b-=r*X,u=$(u,s,R),h+=i*F}if(a.enableLimit){let B=j(C,I);{let w=B-a.lowerTranslation,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(u,p))+A*h-S*b,R=-v*a.axialMass*(T+D)-P*a.lowerImpulse,X=a.lowerImpulse;a.lowerImpulse=Math.max(X+R,0),R=a.lowerImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}{let w=a.upperTranslation-B,D=0,v=1,P=0;w>0?D=w*e.inv_h:o&&(D=e.jointSoftness.biasRate*w,v=e.jointSoftness.massScale,P=e.jointSoftness.impulseScale);let T=j(C,J(p,u))+S*b-A*h,R=-v*a.axialMass*(T+D)-P*a.upperImpulse,X=a.upperImpulse;a.upperImpulse=Math.max(X+R,0),R=a.upperImpulse-X;let F=it(R,C),E=R*S,W=R*A;p=$(p,n,F),b+=r*E,u=yt(u,s,F),h-=i*W}}{let B=de(C),w=0,D=1,v=0;if(o){let et=j(B,I);w=e.jointSoftness.biasRate*et,D=e.jointSoftness.massScale,v=e.jointSoftness.impulseScale}let P=z(U(I,f),B),T=z(y,B),R=j(B,J(u,p))+T*h-P*b,X=-D*a.perpMass*(R+w)-v*a.perpImpulse;a.perpImpulse+=X;let F=it(X,B),E=X*P,W=X*T;p=yt(p,n,F),b-=r*E,u=$(u,s,F),h+=i*W}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function ab(t,e,o,n){let s=e.wheelJoint,r=H(o,e.localOriginAnchorA),i=H(n,e.localOriginAnchorB),c=K(o.q,s.localAxisA),a=V.b2_colorGray7,l=V.b2_colorGreen,d=V.b2_colorRed,p=V.b2_colorGray4,b=V.b2_colorBlue;if(t.DrawSegment(r,i,b,t.context),s.enableLimit){let u=$(r,s.lowerTranslation,c),h=$(r,s.upperTranslation,c),m=de(c);t.DrawSegment(u,h,a,t.context),t.DrawSegment(yt(u,.1,m),$(u,.1,m),l,t.context),t.DrawSegment(yt(h,.1,m),$(h,.1,m),d,t.context)}else t.DrawSegment(yt(r,1,c),$(r,1,c),a,t.context);t.DrawPoint(r.x,r.y,5,a,t.context),t.DrawPoint(i.x,i.y,5,p,t.context)}function cb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.linearOffset=e}function lb(t){return q(t,k.b2_motorJoint).motorJoint.linearOffset}function db(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.angularOffset=ht(e,-wo,wo)}function bb(t){return q(t,k.b2_motorJoint).motorJoint.angularOffset}function pb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxForce=Math.max(0,e)}function ub(t){return q(t,k.b2_motorJoint).motorJoint.maxForce}function hb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.maxTorque=Math.max(0,e)}function mb(t){return q(t,k.b2_motorJoint).motorJoint.maxTorque}function yb(t,e){let o=q(t,k.b2_motorJoint);o.motorJoint.correctionFactor=ht(e,0,1)}function fb(t){return q(t,k.b2_motorJoint).motorJoint.correctionFactor}function xb(t,e){return it(t.inv_h,e.motorJoint.linearImpulse)}function Ib(t,e){return t.inv_h*e.motorJoint.angularImpulse}function Sb(t,e){let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n],a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex,b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.motorJoint;I.indexA=i.setIndex==M.b2_awakeSet?d:x,I.indexB=c.setIndex==M.b2_awakeSet?p:x,I.anchorA=K(b.transform.q,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(u.transform.q,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(J(u.center,b.center),I.linearOffset),I.deltaAngle=oe(u.transform.q,b.transform.q)-I.angularOffset,I.deltaAngle=vo(I.deltaAngle);let C=I.anchorA,_=I.anchorB,S={cx:new g(0,0),cy:new g(0,0)};S.cx.x=h+f+C.y*C.y*m+_.y*_.y*y,S.cx.y=-C.y*C.x*m-_.y*_.x*y,S.cy.x=S.cx.y,S.cy.y=h+f+C.x*C.x*m+_.x*_.x*y,I.linearMass=ss(S);let A=m+y;I.angularMass=A>0?1/A:0,e.enableWarmStarting==!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function _b(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=t.motorJoint,c=new Pt,a=i.indexA==x?c:e.states[i.indexA],l=i.indexB==x?c:e.states[i.indexB],d=K(a.deltaRotation,i.anchorA),p=K(l.deltaRotation,i.anchorB);a.linearVelocity=yt(a.linearVelocity,o,i.linearImpulse),a.angularVelocity-=s*(z(d,i.linearImpulse)+i.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,i.linearImpulse),l.angularVelocity+=r*(z(p,i.linearImpulse)+i.angularImpulse)}function gb(t,e,o){let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.motorJoint,l=a.indexA==x?c:e.states[a.indexA],d=a.indexB==x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=vo(m);let f=e.inv_h*a.correctionFactor*m,y=h-b,I=-a.angularMass*(y+f),C=a.angularImpulse,_=e.h*a.maxTorque;a.angularImpulse=ht(a.angularImpulse+I,-_,_),I=a.angularImpulse-C,b-=r*I,h+=i*I}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=U(J(d.deltaPosition,l.deltaPosition),J(f,m)),I=U(a.deltaCenter,y),C=it(e.inv_h*a.correctionFactor,I),_=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=ns(a.linearMass,U(_,C)),A=new g(-S.x,-S.y),B=a.linearImpulse,w=e.h*a.maxForce;a.linearImpulse=U(a.linearImpulse,A),pe(a.linearImpulse)>w*w&&(a.linearImpulse=lt(a.linearImpulse),a.linearImpulse.x*=w,a.linearImpulse.y*=w),A=J(a.linearImpulse,B),p=yt(p,n,A),b-=r*z(m,A),u=$(u,s,A),h+=i*z(f,A)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Bb(t,e){Hr(t);let o=q(t,k.b2_mouseJoint);o.mouseJoint.targetA=e.clone()}function Ab(t){return q(t,k.b2_mouseJoint).mouseJoint.targetA}function Cb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.hertz=e}function wb(t){return q(t,k.b2_mouseJoint).mouseJoint.hertz}function vb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.dampingRatio=e}function Jb(t){return q(t,k.b2_mouseJoint).mouseJoint.dampingRatio}function Mb(t,e){let o=q(t,k.b2_mouseJoint);o.mouseJoint.maxForce=e}function Db(t){return q(t,k.b2_mouseJoint).mouseJoint.maxForce}function Pb(t,e){return it(t.inv_h,e.mouseJoint.linearImpulse)}function kb(t,e){return t.inv_h*e.mouseJoint.angularImpulse}function Tb(t,e){let o=t.bodyIdB,n=e.world,r=n.bodyArray[o];r.setIndex,M.b2_awakeSet;let i=n.solverSetArray[r.setIndex],c=r.localIndex,a=i.sims.data[c];t.invMassB=a.invMass,t.invIB=a.invInertia;let l=t.mouseJoint;l.indexB=r.setIndex===M.b2_awakeSet?c:x,l.anchorB=K(a.transform.q,J(t.localOriginAnchorB,a.localCenter)),l.linearSoftness=ie(l.hertz,l.dampingRatio,e.h);let d=.5,p=.1;l.angularSoftness=ie(d,p,e.h);let b=l.anchorB,u=a.invMass,h=a.invInertia,m={cx:new g(u+h*b.y*b.y,-h*b.x*b.y),cy:new g(-h*b.x*b.y,u+h*b.x*b.x)};l.linearMass=ss(m),l.deltaCenter=J(a.center,l.targetA),e.enableWarmStarting===!1&&(l.linearImpulse=new g(0,0),l.angularImpulse=0)}function Gb(t,e){t.type,k.b2_mouseJoint;let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity,a=r.deltaRotation,l=K(a,s.anchorB);i=$(i,o,s.linearImpulse),c+=n*(z(l,s.linearImpulse)+s.angularImpulse),r.linearVelocity=i,r.angularVelocity=c}function Rb(t,e){let o=t.invMassB,n=t.invIB,s=t.mouseJoint,r=e.states[s.indexB],i=r.linearVelocity.clone(),c=r.angularVelocity;{let l=s.angularSoftness.massScale,d=s.angularSoftness.impulseScale,p=n>0?-c/n:0;p=l*p-d*s.angularImpulse,s.angularImpulse+=p,c+=n*p}let a=s.maxForce*e.h;{let l=r.deltaRotation,d=K(l,s.anchorB),p=U(i,Gt(c,d)),b=U(U(r.deltaPosition,d),s.deltaCenter),u=it(s.linearSoftness.biasRate,b),h=s.linearSoftness.massScale,m=s.linearSoftness.impulseScale,f=ns(s.linearMass,U(p,u)),y=new g(-h*f.x-m*s.linearImpulse.x,-h*f.y-m*s.linearImpulse.y),I=s.linearImpulse.clone();s.linearImpulse.x+=y.x,s.linearImpulse.y+=y.y,Yt(s.linearImpulse)>a&&(s.linearImpulse=it(a,lt(s.linearImpulse))),y.x=s.linearImpulse.x-I.x,y.y=s.linearImpulse.y-I.y,i=$(i,o,y),c+=n*z(d,y)}r.linearVelocity=i,r.angularVelocity=c}function Lb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearHertz=e}function Eb(t){return q(t,k.b2_weldJoint).weldJoint.linearHertz}function jb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.linearDampingRatio=e}function Fb(t){return q(t,k.b2_weldJoint).weldJoint.linearDampingRatio}function Xb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid hertz value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularHertz=e}function qb(t){return q(t,k.b2_weldJoint).weldJoint.angularHertz}function Vb(t,e){if(!(ae(e)&&e>=0))throw new Error("Invalid dampingRatio value");let o=q(t,k.b2_weldJoint);o.weldJoint.angularDampingRatio=e}function Yb(t){return q(t,k.b2_weldJoint).weldJoint.angularDampingRatio}function Nb(t,e){return it(t.inv_h,e.weldJoint.linearImpulse)}function Wb(t,e){return t.inv_h*e.weldJoint.angularImpulse}function Ob(t,e){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let o=t.bodyIdA,n=t.bodyIdB,s=e.world,r=s.bodyArray,i=r[o],c=r[n];if(!(i.setIndex===M.b2_awakeSet||c.setIndex===M.b2_awakeSet))throw new Error("At least one body must be awake");let a=s.solverSetArray[i.setIndex],l=s.solverSetArray[c.setIndex],d=i.localIndex,p=c.localIndex;if(!(0<=d&&d<=a.sims.count))throw new Error("Invalid localIndexA");if(!(0<=p&&p<=l.sims.count))throw new Error("Invalid localIndexB");let b=a.sims.data[i.localIndex],u=l.sims.data[c.localIndex],h=b.invMass,m=b.invInertia,f=u.invMass,y=u.invInertia;t.invMassA=h,t.invMassB=f,t.invIA=m,t.invIB=y;let I=t.weldJoint;I.indexA=i.setIndex===M.b2_awakeSet?d:x,I.indexB=c.setIndex===M.b2_awakeSet?p:x;let C=b.transform.q,_=u.transform.q;I.anchorA=K(C,J(t.localOriginAnchorA,b.localCenter)),I.anchorB=K(_,J(t.localOriginAnchorB,u.localCenter)),I.deltaCenter=J(u.center,b.center),I.deltaAngle=oe(_,C)-I.referenceAngle;let S=m+y;I.axialMass=S>0?1/S:0,I.linearHertz===0?I.linearSoftness=e.jointSoftness:I.linearSoftness=ie(I.linearHertz,I.linearDampingRatio,e.h),I.angularHertz===0?I.angularSoftness=e.jointSoftness:I.angularSoftness=ie(I.angularHertz,I.angularDampingRatio,e.h),e.enableWarmStarting===!1&&(I.linearImpulse=new g(0,0),I.angularImpulse=0)}function Ub(t,e){let o=t.invMassA,n=t.invMassB,s=t.invIA,r=t.invIB,i=new Pt,c=t.weldJoint,a=c.indexA===x?i:e.states[c.indexA],l=c.indexB===x?i:e.states[c.indexB],d=K(a.deltaRotation,c.anchorA),p=K(l.deltaRotation,c.anchorB);a.linearVelocity=yt(a.linearVelocity,o,c.linearImpulse),a.angularVelocity-=s*(z(d,c.linearImpulse)+c.angularImpulse),l.linearVelocity=$(l.linearVelocity,n,c.linearImpulse),l.angularVelocity+=r*(z(p,c.linearImpulse)+c.angularImpulse)}function zb(t,e,o){if(t.type!==k.b2_weldJoint)throw new Error("Invalid joint type");let n=t.invMassA,s=t.invMassB,r=t.invIA,i=t.invIB,c=new Pt,a=t.weldJoint,l=a.indexA===x?c:e.states[a.indexA],d=a.indexB===x?c:e.states[a.indexB],p=l.linearVelocity,b=l.angularVelocity,u=d.linearVelocity,h=d.angularVelocity;{let m=0,f=1,y=0;if(o||a.angularHertz>0){let _=oe(d.deltaRotation,l.deltaRotation)+a.deltaAngle;m=a.angularSoftness.biasRate*_,f=a.angularSoftness.massScale,y=a.angularSoftness.impulseScale}let I=h-b,C=-f*a.axialMass*(I+m)-y*a.angularImpulse;a.angularImpulse+=C,b-=r*C,h+=i*C}{let m=K(l.deltaRotation,a.anchorA),f=K(d.deltaRotation,a.anchorB),y=new g(0,0),I=1,C=0;if(o||a.linearHertz>0){let w=l.deltaPosition,D=d.deltaPosition,v=U(U(J(D,w),J(f,m)),a.deltaCenter);y=it(a.linearSoftness.biasRate,v),I=a.linearSoftness.massScale,C=a.linearSoftness.impulseScale}let _=J(U(u,Gt(h,f)),U(p,Gt(b,m))),S=new ao;S.cx.x=n+s+m.y*m.y*r+f.y*f.y*i,S.cy.x=-m.y*m.x*r-f.y*f.x*i,S.cx.y=S.cy.x,S.cy.y=n+s+m.x*m.x*r+f.x*f.x*i;let A=zo(S,U(_,y)),B=new g(-I*A.x-C*a.linearImpulse.x,-I*A.y-C*a.linearImpulse.y);a.linearImpulse=U(a.linearImpulse,B),p=yt(p,n,B),b-=r*z(m,B),u=$(u,s,B),h+=i*z(f,B)}l.linearVelocity=p,l.angularVelocity=b,d.linearVelocity=u,d.angularVelocity=h}function Hb(){let t=new Ho;return t.length=1,t.maxLength=De,t}function $b(){let t=new $o;return t.maxForce=1,t.maxTorque=1,t.correctionFactor=.3,t}function Qb(){let t=new Qo;return t.hertz=4,t.dampingRatio=1,t.maxForce=1,t}function Zb(){let t=new Zo;return t.localAxisA=new g(1,0),t}function ia(){let t=new mo;return t.drawSize=.25,t}function tp(){return new tn}function ep(){let t=new en;return t.localAxisA=new g(0,1),t.enableSpring=!0,t.hertz=1,t.dampingRatio=.7,t}function Je(t,e){let o=e.index1-1;return t.jointArray[o]}function Me(t,e){return t.jointArray[e]}function No(t,e){if(e.setIndex===M.b2_awakeSet){let n=t.constraintGraph.colors[e.colorIndex];return e.jointId,n.joints.data[e.localIndex].jointId,n.joints.data[e.localIndex]}return t.solverSetArray[e.setIndex].joints.data[e.localIndex]}function q(t,e){let o=O(t.world0);if(o.locked)return null;let n=Je(o,t);return No(o,n)}var Kb=class{constructor(e=null,o=null){this.joint=e,this.jointSim=o}};function Kn(t,e,o,n,s,r,i){Lt(t);let c=e.id,a=o.id,l=Math.max(e.setIndex,o.setIndex),d=ne(t.jointIdPool);for(;d>=t.jointArray.length;)t.jointArray.push(new la);let p=t.jointArray[d];p.edges=[new zn,new zn],p.jointId=d,p.userData=n,p.setIndex=x,p.colorIndex=x,p.localIndex=x,p.islandId=x,p.islandPrev=x,p.islandNext=x,p.revision+=1,p.drawSize=s,p.type=r,p.isMarked=!1,p.collideConnected=i,p.edges[0].bodyId=c,p.edges[0].prevKey=x,p.edges[0].nextKey=e.headJointKey;let b=d<<1|0;if(e.headJointKey!==x){let f=t.jointArray[e.headJointKey>>1].edges[e.headJointKey&1];f.prevKey=b}e.headJointKey=b,e.jointCount+=1,p.edges[1].bodyId=a,p.edges[1].prevKey=x,p.edges[1].nextKey=o.headJointKey;let u=d<<1|1;if(o.headJointKey!==x){let f=t.jointArray[o.headJointKey>>1].edges[o.headJointKey&1];f.prevKey=u}o.headJointKey=u,o.jointCount+=1;let h;if(e.setIndex===M.b2_disabledSet||o.setIndex===M.b2_disabledSet){let m=t.solverSetArray[M.b2_disabledSet];p.setIndex=M.b2_disabledSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_staticSet&&o.setIndex===M.b2_staticSet){let m=t.solverSetArray[M.b2_staticSet];p.setIndex=M.b2_staticSet,p.localIndex=m.joints.length,h=oo(m.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a}else if(e.setIndex===M.b2_awakeSet||o.setIndex===M.b2_awakeSet)l>=M.b2_firstSleepingSet&&qe(t,l),p.setIndex=M.b2_awakeSet,h=$i(t,p),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a;else{let m=l,f=t.solverSetArray[m];p.setIndex=m,p.localIndex=f.joints.length,h=oo(f.joints),h.jointId=d,h.bodyIdA=c,h.bodyIdB=a,e.setIndex!==o.setIndex&&e.setIndex>=M.b2_firstSleepingSet&&o.setIndex>=M.b2_firstSleepingSet&&(rl(t,e.setIndex,o.setIndex),m=e.setIndex,h=t.solverSetArray[m].joints[p.localIndex])}return p.setIndex>M.b2_disabledSet&&Ys(t,p,!0),Lt(t),new Kb(p,h)}function Hn(t,e,o){let n,s;e.contactCount>1,c=n&1,a=t.contactArray[i];n=a.edges[c].nextKey;let l=c^1;a.edges[l].bodyId===s&&xo(t,a,r)}Lt(t)}function $r(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_distanceJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_distanceJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.distanceJoint=new da,i.distanceJoint.length=Math.max(e.length,It),i.distanceJoint.hertz=e.hertz,i.distanceJoint.dampingRatio=e.dampingRatio,i.distanceJoint.minLength=Math.max(e.minLength,It),i.distanceJoint.maxLength=Math.max(e.minLength,e.maxLength),i.distanceJoint.maxMotorForce=e.maxMotorForce,i.distanceJoint.motorSpeed=e.motorSpeed,i.distanceJoint.enableSpring=e.enableSpring,i.distanceJoint.enableLimit=e.enableLimit,i.distanceJoint.enableMotor=e.enableMotor,i.distanceJoint.impulse=0,i.distanceJoint.lowerImpulse=0,i.distanceJoint.upperImpulse=0,i.distanceJoint.motorImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Qr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_motorJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_motorJoint,i.localOriginAnchorA=new g(0,0),i.localOriginAnchorB=new g(0,0),i.motorJoint=new ba,i.motorJoint.linearOffset=e.linearOffset,i.motorJoint.angularOffset=e.angularOffset,i.motorJoint.maxForce=e.maxForce,i.motorJoint.maxTorque=e.maxTorque,i.motorJoint.correctionFactor=ht(e.correctionFactor,0,1),e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function Zr(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Rt(o,n),i=Rt(o,s),c=Kn(o,n,s,e.userData,1,k.b2_mouseJoint,e.collideConnected),a=c.jointSim;return a.type=k.b2_mouseJoint,a.localOriginAnchorA=Re(r,e.target),a.localOriginAnchorB=Re(i,e.target),a.mouseJoint=new pa,a.mouseJoint.targetA=e.target,a.mouseJoint.hertz=e.hertz,a.mouseJoint.dampingRatio=e.dampingRatio,a.mouseJoint.maxForce=e.maxForce,new zt(a.jointId+1,o.worldId,c.joint.revision)}function Sn(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,e.drawSize,k.b2_revoluteJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_revoluteJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.revoluteJoint=new ha,i.revoluteJoint.referenceAngle=ht(e.referenceAngle,-Math.PI,Math.PI),i.revoluteJoint.linearImpulse=new g(0,0),i.revoluteJoint.axialMass=0,i.revoluteJoint.springImpulse=0,i.revoluteJoint.motorImpulse=0,i.revoluteJoint.lowerImpulse=0,i.revoluteJoint.upperImpulse=0,i.revoluteJoint.hertz=e.hertz,i.revoluteJoint.dampingRatio=e.dampingRatio,i.revoluteJoint.lowerAngle=Math.min(e.lowerAngle,e.upperAngle),i.revoluteJoint.upperAngle=Math.max(e.lowerAngle,e.upperAngle),i.revoluteJoint.lowerAngle=ht(i.revoluteJoint.lowerAngle,-Math.PI,Math.PI),i.revoluteJoint.upperAngle=ht(i.revoluteJoint.upperAngle,-Math.PI,Math.PI),i.revoluteJoint.maxMotorTorque=e.maxMotorTorque,i.revoluteJoint.motorSpeed=e.motorSpeed,i.revoluteJoint.enableSpring=e.enableSpring,i.revoluteJoint.enableLimit=e.enableLimit,i.revoluteJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ti(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_prismaticJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_prismaticJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.prismaticJoint=new ua,i.prismaticJoint.localAxisA=lt(e.localAxisA),i.prismaticJoint.referenceAngle=e.referenceAngle,i.prismaticJoint.impulse=new g(0,0),i.prismaticJoint.axialMass=0,i.prismaticJoint.springImpulse=0,i.prismaticJoint.motorImpulse=0,i.prismaticJoint.lowerImpulse=0,i.prismaticJoint.upperImpulse=0,i.prismaticJoint.hertz=e.hertz,i.prismaticJoint.dampingRatio=e.dampingRatio,i.prismaticJoint.lowerTranslation=e.lowerTranslation,i.prismaticJoint.upperTranslation=e.upperTranslation,i.prismaticJoint.maxMotorForce=e.maxMotorForce,i.prismaticJoint.motorSpeed=e.motorSpeed,i.prismaticJoint.enableSpring=e.enableSpring,i.prismaticJoint.enableLimit=e.enableLimit,i.prismaticJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function ei(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_weldJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_weldJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.weldJoint=new ma,i.weldJoint.referenceAngle=e.referenceAngle,i.weldJoint.linearHertz=e.linearHertz,i.weldJoint.linearDampingRatio=e.linearDampingRatio,i.weldJoint.angularHertz=e.angularHertz,i.weldJoint.angularDampingRatio=e.angularDampingRatio,i.weldJoint.linearImpulse=new g(0,0),i.weldJoint.angularImpulse=0,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function oi(t,e){let o=gt(t);if(o.locked)return new zt;let n=Z(o,e.bodyIdA),s=Z(o,e.bodyIdB),r=Kn(o,n,s,e.userData,1,k.b2_wheelJoint,e.collideConnected),i=r.jointSim;return i.type=k.b2_wheelJoint,i.localOriginAnchorA=e.localAnchorA,i.localOriginAnchorB=e.localAnchorB,i.wheelJoint=new ya,i.wheelJoint.localAxisA=lt(e.localAxisA),i.wheelJoint.perpMass=0,i.wheelJoint.axialMass=0,i.wheelJoint.motorImpulse=0,i.wheelJoint.lowerImpulse=0,i.wheelJoint.upperImpulse=0,i.wheelJoint.lowerTranslation=e.lowerTranslation,i.wheelJoint.upperTranslation=e.upperTranslation,i.wheelJoint.maxMotorTorque=e.maxMotorTorque,i.wheelJoint.motorSpeed=e.motorSpeed,i.wheelJoint.hertz=e.hertz,i.wheelJoint.dampingRatio=e.dampingRatio,i.wheelJoint.enableSpring=e.enableSpring,i.wheelJoint.enableLimit=e.enableLimit,i.wheelJoint.enableMotor=e.enableMotor,e.collideConnected===!1&&Hn(o,n,s),new zt(i.jointId+1,o.worldId,r.joint.revision)}function aa(t,e,o){let n=e.jointId,s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c);if(s.prevKey!==x){let m=t.jointArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.jointArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let d=n<<1|0;if(a.headJointKey===d&&(a.headJointKey=s.nextKey),a.jointCount-=1,r.prevKey!==x){let m=t.jointArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.jointArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let p=n<<1|1;l.headJointKey===p&&(l.headJointKey=r.nextKey),l.jointCount-=1,e.islandId!==x&&Ns(t,e);let b=e.setIndex,u=e.localIndex;if(b===M.b2_awakeSet)Tr(t,e.edges[0].bodyId,e.edges[1].bodyId,e.colorIndex,u);else{let h=t.solverSetArray[b];if(bn(h.joints,u)!==x){let y=h.joints.data[u].jointId,I=t.jointArray[y];I.localIndex=u}}e.setIndex=x,e.colorIndex=x,e.localIndex=x,e.jointId=x,e.type=k.b2_unknown,xe(t.jointIdPool,n),o&&(Ot(t,a),Ot(t,l)),Lt(t)}function ni(t){let e=O(t.world0);if(e.locked)return;let o=Je(e,t);aa(e,o,!0)}function op(t){let e=O(t.world0);return Je(e,t).type}function np(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[0].bodyId)}function sp(t){let e=O(t.world0),o=Je(e,t);return Ps(e,o.edges[1].bodyId)}function rp(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorA}function ip(t){let e=O(t.world0),o=Je(e,t);return No(e,o).localOriginAnchorB}function ap(t,e){let o=ft(t.world0);if(o===null)return;let n=Je(o,t);if(n.collideConnected===e)return;n.collideConnected=e;let s=_t(o,n.edges[0].bodyId),r=_t(o,n.edges[1].bodyId);if(e){let i=s.shapeCount,c=r.shapeCount,a=i=M.b2_firstSleepingSet&&qe(t,r.setIndex),r.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet&&qe(t,s.setIndex);let i=s.islandId,c=r.islandId;if(i===c){up(t,i,e);return}let a=null;if(i!==x){a=go(t,i);let d=a.parentIsland;for(;d!==x;){let p=go(t,d);p.parentIsland!==x&&(a.parentIsland=p.parentIsland),a=p,i=d,d=a.parentIsland}}let l=null;if(c!==x){l=go(t,c);let d=l.parentIsland;for(;l.parentIsland!==x;){let p=go(t,d);p.parentIsland!==x&&(l.parentIsland=p.parentIsland),l=p,c=d,d=l.parentIsland}}a!==l&&a!==null&&l!==null&&(l.parentIsland=i),a!==null?up(t,i,e):up(t,c,e)}function ri(t,e){let o=e.islandId,n=go(t,o);if(e.islandPrev!==x){let s=t.contactArray[e.islandPrev];s.islandNext=e.islandNext}if(e.islandNext!==x){let s=t.contactArray[e.islandNext];s.islandPrev=e.islandPrev}n.headContact===e.contactId&&(n.headContact=e.islandNext),n.tailContact===e.contactId&&(n.tailContact=e.islandPrev),n.contactCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function hp(t,e,o){let n=t.islandArray[e];if(n.headJoint!==x){o.islandNext=n.headJoint;let s=Me(t,n.headJoint);s.islandPrev=o.jointId}n.headJoint=o.jointId,n.tailJoint===x&&(n.tailJoint=n.headJoint),n.jointCount+=1,o.islandId=e,Bo(t,e)}function Ys(t,e,o){let n=_t(t,e.edges[0].bodyId),s=_t(t,e.edges[1].bodyId);n.setIndex===M.b2_awakeSet&&s.setIndex>=M.b2_firstSleepingSet?qe(t,s.setIndex):s.setIndex===M.b2_awakeSet&&n.setIndex>=M.b2_firstSleepingSet&&qe(t,n.setIndex);let r=n.islandId,i=s.islandId;if(r===i){hp(t,r,e);return}let c=null;if(r!==x)for(c=go(t,r);c.parentIsland!==x;){let l=go(t,c.parentIsland);l.parentIsland!==x&&(c.parentIsland=l.parentIsland),r=c.parentIsland,c=l}let a=null;if(i!==x)for(a=go(t,i);a.parentIsland!==x;){let l=go(t,a.parentIsland);l.parentIsland!==x&&(a.parentIsland=l.parentIsland),i=a.parentIsland,a=l}c!==a&&c!==null&&a!==null&&(a.parentIsland=r),c!==null?hp(t,r,e):hp(t,i,e),o&&Un(t)}function Ns(t,e){let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let s=Me(t,e.islandPrev);s.islandNext=e.islandNext}if(e.islandNext!==x){let s=Me(t,e.islandNext);s.islandPrev=e.islandPrev}n.headJoint===e.jointId&&(n.headJoint=e.islandNext),n.tailJoint===e.jointId&&(n.tailJoint=e.islandPrev),n.jointCount-=1,n.constraintRemoveCount+=1,e.islandId=x,e.islandPrev=x,e.islandNext=x,Bo(t,o)}function qm(t,e){let o=e.parentIsland,n=t.islandArray[o],s=e.headBody;for(;s!==x;){let l=_t(t,s);l.islandId=o,s=l.islandNext}let r=e.headContact;for(;r!==x;){let l=t.contactArray[r];l.islandId=o,r=l.islandNext}let i=e.headJoint;for(;i!==x;){let l=Me(t,i);l.islandId=o,i=l.islandNext}let c=_t(t,n.tailBody);c.islandNext=e.headBody;let a=_t(t,e.headBody);if(a.islandPrev=n.tailBody,n.tailBody=e.tailBody,n.bodyCount+=e.bodyCount,n.headContact===x)n.headContact=e.headContact,n.tailContact=e.tailContact,n.contactCount=e.contactCount;else if(e.headContact!==x){let l=t.contactArray[n.tailContact];l.islandNext=e.headContact;let d=t.contactArray[e.headContact];d.islandPrev=n.tailContact,n.tailContact=e.tailContact,n.contactCount+=e.contactCount}if(n.headJoint===x)n.headJoint=e.headJoint,n.tailJoint=e.tailJoint,n.jointCount=e.jointCount;else if(e.headJoint!==x){let l=Me(t,n.tailJoint);l.islandNext=e.headJoint;let d=Me(t,e.headJoint);d.islandPrev=n.tailJoint,n.tailJoint=e.tailJoint,n.jointCount+=e.jointCount}n.constraintRemoveCount+=e.constraintRemoveCount,Bo(t,o)}function Un(t){let e=t.solverSetArray[M.b2_awakeSet],o=e.islands.data,n=e.islands.count,s=t.islandArray;for(let r=0;r=0;--r){let i=o[r].islandId,c=s[i];c.parentIsland!==x&&(qm(t,c),si(t,i))}ii(t)}function Ur(t,e){let o=t.islandArray[e],n=o.setIndex;if(n!==M.b2_awakeSet||o.constraintRemoveCount===0)return;Bo(t,e);let s=o.bodyCount,r=t.bodyArray,i=t.contactArray,c=[],a=[],l=o.headBody;for(;l!==x;){a.push(l);let b=r[l];b.isMarked=!1,l=b.islandNext}let d=o.headContact;for(;d!==x;){let b=i[d];b.isMarked=!1,d=b.islandNext}let p=o.headJoint;for(;p!==x;){let b=Me(t,p);b.isMarked=!1,p=b.islandNext}si(t,e);for(let b=0;b0;){let y=c.pop(),I=r[y];I.islandId=f,m.tailBody!==x&&(r[m.tailBody].islandNext=y),I.islandPrev=m.tailBody,I.islandNext=x,m.tailBody=y,m.headBody===x&&(m.headBody=y),m.bodyCount+=1;let C=I.headContactKey;for(;C!==x;){let S=C>>1,A=C&1,B=t.contactArray[S];if(C=B.edges[A].nextKey,B.isMarked||B.flags&mt.b2_contactSensorFlag||!(B.flags&mt.b2_contactTouchingFlag))continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.isMarked===!1&&v.setIndex!==M.b2_staticSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailContact!==x){let P=t.contactArray[m.tailContact];P.islandNext=S}B.islandPrev=m.tailContact,B.islandNext=x,m.tailContact=S,m.headContact===x&&(m.headContact=S),m.contactCount+=1}let _=I.headJointKey;for(;_!==x;){let S=_>>1,A=_&1,B=Me(t,S);if(_=B.edges[A].nextKey,B.isMarked)continue;B.isMarked=!0;let w=A^1,D=B.edges[w].bodyId,v=r[D];if(v.setIndex!==M.b2_disabledSet){if(v.isMarked===!1&&v.setIndex===M.b2_awakeSet&&(c.push(D),v.isMarked=!0),B.islandId=f,m.tailJoint!==x){let P=Me(t,m.tailJoint);P.islandNext=S}B.islandPrev=m.tailJoint,B.islandNext=x,m.tailJoint=S,m.headJoint===x&&(m.headJoint=S),m.jointCount+=1}}}Bo(t,f)}}function Bo(t,e){if(!uo)return;se(t.islandArray,e);let o=t.islandArray[e];{let n=t.bodyArray;o.bodyCount>1;let s=0,r=o.headBody;for(;r!=x;){se(n,r);let i=n[r];s+=1,s==o.bodyCount,r=i.islandNext}}if(o.headContact!=x){o.contactCount>1;let n=0,s=o.headContact;for(;s!=x;){se(t.contactArray,s);let r=t.contactArray[s];n+=1,n==o.contactCount,s=r.islandNext}}if(o.headJoint!=x){o.jointCount>1;let n=0,s=o.headJoint;for(;s!=x;){se(t.jointArray,s);let r=t.jointArray[s];n+=1,n==o.jointCount,s=r.islandNext}}}function ra(t,e){return e.c1.x=t.center0X,e.c1.y=t.center0Y,e.c2.copy(t.center),e.q1.copy(t.rotation0),e.q2.copy(t.transform.q),e.localCenter.copy(t.localCenter),e}function _t(t,e){return t.bodyArray[e]}function Z(t,e){return _t(t,e.index1-1)}function Rt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex].transform}function le(t,e){let o=t.bodyArray[e];return Rt(t,o)}function Ps(t,e){let o=t.bodyArray[e];return new Ee(e+1,t.worldId,o.revision)}function jt(t,e){return t.solverSetArray[e.setIndex].sims.data[e.localIndex]}function $n(t,e){return e.setIndex===M.b2_awakeSet?t.solverSetArray[M.b2_awakeSet].states.data[e.localIndex]:null}function yp(t,e,o){let n=xa(t,e);o.islandId=n.islandId,n.headBody=o.id,n.tailBody=o.id,n.bodyCount=1}function fp(t,e){if(e.islandId===x)return;let o=e.islandId,n=t.islandArray[o];if(e.islandPrev!==x){let r=_t(t,e.islandPrev);r.islandNext=e.islandNext}if(e.islandNext!==x){let r=_t(t,e.islandNext);r.islandPrev=e.islandPrev}n.bodyCount-=1;let s=!1;n.headBody===e.id?(n.headBody=e.islandNext,n.headBody===x&&(si(t,n.islandId),s=!0)):n.tailBody===e.id&&(n.tailBody=e.islandPrev),s===!1&&Bo(t,o),e.islandId=x,e.islandPrev=x,e.islandNext=x}function xp(t,e,o){let n=e.headContactKey;for(;n!==x;){let s=n>>1,r=n&1,i=t.contactArray[s];n=i.edges[r].nextKey,xo(t,i,o)}Lt(t)}function Ao(t,e){let o=gt(t);if(o.locked)return new Ee(0,0,0);let n=(e.isAwake||e.enableSleep===!1)&&e.isEnabled,s;if(e.isEnabled===!1)s=M.b2_disabledSet;else if(e.type===tt.b2_staticBody)s=M.b2_staticSet;else if(n===!0)s=M.b2_awakeSet;else{if(s=ne(o.solverSetIdPool),s===o.solverSetArray.length){let l=new so;l.setIndex=s,o.solverSetArray.push(l)}o.solverSetArray[s].setIndex=s}let r=ne(o.bodyIdPool),i=o.solverSetArray[s],c=mn(i.sims);if(Object.assign(c,{transform:new at(e.position,e.rotation),center:e.position.clone(),rotation0:e.rotation,center0X:e.position.x,center0Y:e.position.y,localCenter:new g,force:new g,torque:0,mass:0,invMass:0,inertia:0,invInertia:0,minExtent:De,maxExtent:0,linearDamping:e.linearDamping,angularDamping:e.angularDamping,gravityScale:e.gravityScale,bodyId:r,isBullet:e.isBullet,allowFastRotation:e.allowFastRotation,enlargeAABB:!1,isFast:!1,isSpeedCapped:!1}),s===M.b2_awakeSet){let l=js(i.states);Object.assign(l,{linearVelocity:e.linearVelocity,angularVelocity:e.angularVelocity,deltaRotation:new rt})}for(;r>=o.bodyArray.length;)o.bodyArray.push(new _a);let a=o.bodyArray[r];return Object.assign(a,{userData:e.userData,setIndex:s,localIndex:i.sims.count-1,revision:a.revision+1,headShapeId:x,shapeCount:0,headChainId:x,headContactKey:x,contactCount:0,headJointKey:x,jointCount:0,islandId:x,islandPrev:x,islandNext:x,bodyMoveIndex:x,id:r,sleepThreshold:e.sleepThreshold,sleepTime:0,type:e.type,enableSleep:e.enableSleep,fixedRotation:e.fixedRotation,isSpeedCapped:!1,isMarked:!1,updateBodyMass:e.updateBodyMass}),s>=M.b2_awakeSet&&yp(o,s,a),Lt(o),new Ee(r+1,o.worldId,a.revision)}function Ot(t,e){return e.setIndex>=M.b2_firstSleepingSet?(qe(t,e.setIndex),!0):!1}function _n(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t),n=!0,s=o.headJointKey;for(;s!==x;){let l=s>>1,d=s&1,p=e.jointArray[l];s=p.edges[d].nextKey,aa(e,p,n)}xp(e,o,n);let r=o.headShapeId;for(;r!==x;){let l=e.shapeArray[r];an(l,e.broadPhase),xe(e.shapeIdPool,r),l.id=x,r=l.nextShapeId}let i=o.headChainId;for(;i!==x;){let l=e.chainArray[i];l.shapeIndices=null,xe(e.chainIdPool,i),l.id=x,i=l.nextChainId}fp(e,o);let c=e.solverSetArray[o.setIndex];if(Fs(c.sims,o.localIndex)!==x){let d=c.sims.data[o.localIndex].bodyId,p=e.bodyArray[d];p.localIndex=o.localIndex}if(o.setIndex===M.b2_awakeSet){let l=Xs(c.states,o.localIndex)}else c.setIndex>=M.b2_firstSleepingSet&&c.sims.count==0&&Wn(e,c.setIndex);xe(e.bodyIdPool,o.id),o.setIndex=x,o.localIndex=x,o.id=x,Lt(e)}function Ip(t){let e=ft(t.world0);return e===null?0:Z(e,t).contactCount}function Sp(t,e,o){let n=ft(t.world0);if(n===null)return 0;let r=Z(n,t).headContactKey,i=0;for(;r!==x&&i>1,a=r&1,l=n.contactArray[c];if(l.flags&mt.b2_contactTouchingFlag){let d=n.shapeArray[l.shapeIdA],p=n.shapeArray[l.shapeIdB];e[i].shapeIdA=new St(d.id+1,t.world0,d.revision),e[i].shapeIdB=new St(p.id+1,t.world0,p.revision);let b=Yn(n,l);e[i].manifold=b.manifold,i+=1}r=l.edges[a].nextKey}return i}function _p(t){let e=ft(t.world0);if(e===null)return new xt;let o=Z(e,t);if(o.headShapeId===x){let r=le(e,o.id);return new xt(r.p.x,r.p.y,r.p.x,r.p.y)}let n=e.shapeArray[o.headShapeId],s=n.aabb;for(;n.nextShapeId!==x;)n=e.shapeArray[n.nextShapeId],s=qt(s,n.aabb);return s}function cn(t,e){let o=jt(t,e);if(o.mass=0,o.invMass=0,o.inertia=0,o.invInertia=0,o.minExtent=De,o.maxExtent=0,e.type!==tt.b2_dynamicBody){if(o.center=o.transform.p.clone(),e.type===tt.b2_kinematicBody){let c=e.headShapeId;for(;c!==x;){let a=t.shapeArray[c];c=a.nextShapeId;let l=Yi(a,new g);o.minExtent=Math.min(o.minExtent,l.minExtent),o.maxExtent=Math.max(o.maxExtent,l.maxExtent)}}return}let n=new g,s=e.headShapeId;for(;s!==x;){let c=t.shapeArray[s];if(s=c.nextShapeId,c.density===0)continue;let a=Za(c);o.mass+=a.mass,n=$(n,a.mass,a.center),o.inertia+=a.rotationalInertia}o.mass>0&&(o.invMass=1/o.mass,n=it(o.invMass,n)),o.inertia>0&&e.fixedRotation===!1?(o.inertia-=o.mass*j(n,n),o.invInertia=1/o.inertia):(o.inertia=0,o.invInertia=0);let r=o.center.clone();o.localCenter=n,o.center=H(o.transform,o.localCenter);let i=$n(t,e);if(i!==null){let c=Gt(i.angularVelocity,J(o.center,r));i.linearVelocity=U(i.linearVelocity,c)}for(s=e.headShapeId;s!==x;){let c=t.shapeArray[s];s=c.nextShapeId;let a=Yi(c,n);o.minExtent=Math.min(o.minExtent,a.minExtent),o.maxExtent=Math.max(o.maxExtent,a.maxExtent)}}function gp(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).p}function Us(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o).q}function ai(t){let e=O(t.world0),o=Z(e,t);return Rt(e,o)}function zs(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Re(s,e)}function Bp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return H(s,e)}function Ap(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return Ie(s.q,e)}function Cp(t,e){let o=O(t.world0),n=Z(o,t),s=Rt(o,n);return K(s.q,e)}function Ks(t,e,o){let n=O(t.world0),s=Z(n,t),r=jt(n,s);r.transform.p=e,o!==void 0&&(r.transform.q=o),r.center=H(r.transform,r.localCenter),r.rotation0=r.transform.q,r.center0X=r.center.x,r.center0Y=r.center.y;let i=n.broadPhase,c=r.transform,a=vn,l=Qt,d=s.headShapeId;for(;d!==x;){let p=n.shapeArray[d],b=Xo(p,c);if(b.lowerBoundX-=l,b.lowerBoundY-=l,b.upperBoundX+=l,b.upperBoundY+=l,p.aabb=b,Jo(p.fatAABB,b)===!1){let u=new xt(b.lowerBoundX-a,b.lowerBoundY-a,b.upperBoundX+a,b.upperBoundY+a);p.fatAABB=u,p.proxyKey!==x&&Dr(i,p.proxyKey,u)}d=p.nextShapeId}}function wp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.linearVelocity.clone():new g}function vp(t){let e=O(t.world0),o=Z(e,t),n=$n(e,o);return n!==null?n.angularVelocity:0}function Jp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody)return;pe(e)>0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.linearVelocity=e)}function Mp(t,e){let o=O(t.world0),n=Z(o,t);if(n.type==tt.b2_staticBody||n.fixedRotation)return;e!==0&&Ot(o,n);let s=$n(o,n);s!==null&&(s.angularVelocity=e)}function Dp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=jt(s,r);i.force=U(i.force,e),i.torque+=z(J(o,i.center),e)}}function Ia(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.force=U(r.force,e)}}function Pp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=jt(n,s);r.torque+=e}}function kp(t,e,o,n){let s=O(t.world0),r=Z(s,t);if(n&&r.setIndex>=M.b2_firstSleepingSet&&Ot(s,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=s.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.linearVelocity=$(a.linearVelocity,l.invMass,e),a.angularVelocity+=l.invInertia*z(J(o,l.center),e)}}function Tp(t,e,o){let n=O(t.world0),s=Z(n,t);if(o&&s.setIndex>=M.b2_firstSleepingSet&&Ot(n,s),s.setIndex===M.b2_awakeSet){let r=s.localIndex,i=n.solverSetArray[M.b2_awakeSet],c=i.states.data[r],a=i.sims.data[r];c.linearVelocity=$(c.linearVelocity,a.invMass,e)}}function Gp(t,e,o){let n=O(t.world0),s=t.index1-1,r=n.bodyArray[s];if(o&&r.setIndex>=M.b2_firstSleepingSet&&Ot(n,r),r.setIndex===M.b2_awakeSet){let i=r.localIndex,c=n.solverSetArray[M.b2_awakeSet],a=c.states.data[i],l=c.sims.data[i];a.angularVelocity+=l.invInertia*e}}function Rp(t){let e=O(t.world0);return Z(e,t).type}function Lp(t,e){let o=O(t.world0),n=Z(o,t),s=n.type;if(s===e)return;if(n.setIndex===M.b2_disabledSet){n.type=e,cn(o,n);return}xp(o,n,!1),Ot(o,n);{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];l.islandId!==x&&Ns(o,l);let d=o.bodyArray[l.edges[0].bodyId],p=o.bodyArray[l.edges[1].bodyId];Ot(o,d),Ot(o,p),i=l.edges[a].nextKey}}if(n.type=e,s===tt.staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,c,i,n),yp(o,M.b2_awakeSet,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];u.setIndex===M.b2_staticSet?_o(o,c,i,u):u.setIndex===M.b2_awakeSet&&(_o(o,i,c,u),_o(o,c,i,u)),a=u.edges[b].nextKey}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase);let b=!0,u=e;Vn(p,o.broadPhase,u,l,b)}}else if(e===tt.b2_staticBody){let i=o.solverSetArray[M.b2_staticSet],c=o.solverSetArray[M.b2_awakeSet];Ls(o,i,c,n),fp(o,n);let a=n.headJointKey;for(;a!==x;){let p=a>>1,b=a&1,u=o.jointArray[p];a=u.edges[b].nextKey;let h=b^1,m=o.bodyArray[u.edges[h].bodyId];u.setIndex!==M.b2_disabledSet&&(m.setIndex===M.b2_staticSet?_o(o,i,c,u):(_o(o,i,c,u),_o(o,c,i,u)))}let l=Rt(o,n),d=n.headShapeId;for(;d!==x;){let p=o.shapeArray[d];d=p.nextShapeId,an(p,o.broadPhase),Vn(p,o.broadPhase,tt.b2_staticBody,l,!0)}}else{let i=Rt(o,n),c=n.headShapeId;for(;c!==x;){let a=o.shapeArray[c];c=a.nextShapeId,an(a,o.broadPhase);let l=e;Vn(a,o.broadPhase,l,i,!0)}}{let i=n.headJointKey;for(;i!==x;){let c=i>>1,a=i&1,l=o.jointArray[c];i=l.edges[a].nextKey;let d=a^1,p=l.edges[d].bodyId,b=o.bodyArray[p];b.setIndex!==M.b2_disabledSet&&(n.type===tt.b2_staticBody&&b.type===tt.b2_staticBody||Ys(o,l,!1))}Un(o)}cn(o,n),Lt(o)}function gn(t,e){let o=O(t.world0),n=Z(o,t);n.userData=e}function Ep(t){let e=O(t.world0);return Z(e,t).userData}function jp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).mass}function Fp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).inertia}function Xp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).localCenter.clone()}function qp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).center.clone()}function Vp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.mass=e.mass,s.inertia=e.rotationalInertia,s.localCenter=e.center;let r=H(s.transform,e.center);s.center=r,s.center0X=r.x,s.center0Y=r.y,s.invMass=s.mass>0?1/s.mass:0,s.invInertia=s.inertia>0?1/s.inertia:0}function Yp(t){let e=O(t.world0),o=Z(e,t),n=jt(e,o),s=new je;return s.mass=n.mass,s.center=n.localCenter,s.rotationalInertia=n.inertia,s}function Np(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);cn(e,o)}function Wp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.linearDamping=e}function Op(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).linearDamping}function Up(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.angularDamping=e}function zp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).angularDamping}function Kp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.gravityScale=e}function Hp(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).gravityScale}function $p(t){let e=O(t.world0);return Z(e,t).setIndex===M.b2_awakeSet}function Qp(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);e&&n.setIndex>=M.b2_firstSleepingSet?Ot(o,n):e===!1&&n.setIndex===M.b2_awakeSet&&(o.islandArray[n.islandId].constraintRemoveCount>0&&Ur(o,n.islandId),Yr(o,n.islandId))}function Zp(t){let e=O(t.world0);return Z(e,t).setIndex!==M.b2_disabledSet}function tu(t){let e=O(t.world0);return Z(e,t).enableSleep}function eu(t,e){let o=O(t.world0),n=Z(o,t);n.sleepThreshold=e}function ou(t){let e=O(t.world0);return Z(e,t).sleepThreshold}function nu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);n.enableSleep=e,e===!1&&Ot(o,n)}function su(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex===M.b2_disabledSet)return;xp(e,o,!0),fp(e,o);let s=o.headShapeId;for(;s!==x;){let a=e.shapeArray[s];s=a.nextShapeId,an(a,e.broadPhase)}let r=e.solverSetArray[o.setIndex],i=e.solverSetArray[M.b2_disabledSet];Ls(e,i,r,o);let c=o.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=e.jointArray[a];if(c=d.edges[l].nextKey,d.setIndex===M.b2_disabledSet)continue;d.islandId!==x&&Ns(e,d);let p=e.solverSetArray[d.setIndex];_o(e,i,p,d)}ii(e),Lt(e)}function ru(t){let e=ft(t.world0);if(e===null)return;let o=Z(e,t);if(o.setIndex!==M.b2_disabledSet)return;let n=e.solverSetArray[M.b2_disabledSet],s=o.type===tt.b2_staticBody?M.b2_staticSet:M.b2_awakeSet,r=e.solverSetArray[s];Ls(e,r,n,o);let i=Rt(e,o),c=o.type,a=!0,l=o.headShapeId;for(;l!==x;){let b=e.shapeArray[l];l=b.nextShapeId,Vn(b,e.broadPhase,c,i,a)}s!==M.b2_staticSet&&yp(e,s,o);let d=!1,p=o.headJointKey;for(;p!==x;){let b=p>>1,u=p&1,h=e.jointArray[b];p=h.edges[u].nextKey;let m=e.bodyArray[h.edges[0].bodyId],f=e.bodyArray[h.edges[1].bodyId];if(m.setIndex===M.b2_disabledSet||f.setIndex===M.b2_disabledSet)continue;let y;m.setIndex===M.b2_staticSet&&f.setIndex===M.b2_staticSet?y=M.b2_staticSet:m.setIndex===M.b2_staticSet?y=f.setIndex:y=m.setIndex;let I=e.solverSetArray[y];_o(e,I,n,h),y!==M.b2_staticSet&&Ys(e,h,d)}Un(e),Lt(e)}function iu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t);if(n.fixedRotation!==e){n.fixedRotation=e;let s=$n(o,n);s!==null&&(s.angularVelocity=0),cn(o,n)}}function au(t){let e=O(t.world0);return Z(e,t).fixedRotation}function cu(t,e){let o=ft(t.world0);if(o===null)return;let n=Z(o,t),s=jt(o,n);s.isBullet=e}function lu(t){let e=O(t.world0),o=Z(e,t);return jt(e,o).isBullet}function du(t,e){let o=O(t.world0),s=Z(o,t).headShapeId;for(;s!==x;){let r=o.shapeArray[s];r.enableHitEvents=e,s=r.nextShapeId}}function bu(t){let e=O(t.world0);return Z(e,t).shapeCount}function Sa(t,e){let o=O(t.world0),s=Z(o,t).headShapeId,r=0;for(;s!==x;){let i=o.shapeArray[s],c=new St(i.id+1,t.world0,i.revision);e[r]=c,r+=1,s=i.nextShapeId}return r}function pu(t){let e=O(t.world0);return Z(e,t).jointCount}function uu(t,e,o){let n=O(t.world0),r=Z(n,t).headJointKey,i=0;for(;r!==x&&i>1,a=r&1,l=Me(n,c),d=new zt;d.index1=c+1,d.world0=t.world0,d.revision=l.revision,e[i]=d,i+=1,r=l.edges[a].nextKey}return i}function zr(t,e,o){if(e.type!==tt.b2_dynamicBody&&o.type!==tt.b2_dynamicBody)return!1;let n,s;for(e.jointCount>1,i=n&1,c=i^1,a=Me(t,r);if(a.collideConnected===!1&&a.edges[c].bodyId===s)return!1;n=a.edges[i].nextKey}return!0}function Wo(t){let e=o=>{typeof o=="object"&&o!==null&&Object.keys(o).forEach(n=>{switch(typeof o[n]){case"number":o[n]=0;break;case"boolean":o[n]=!1;break;case"string":o[n]="";break;case"object":Array.isArray(o[n])||(o[n]!==null?e(o[n]):o[n]=null);break}})};e(t)}var _a=class{constructor(){this.userData=null,this.setIndex=0,this.localIndex=0,this.headContactKey=0,this.contactCount=0,this.headShapeId=0,this.shapeCount=0,this.headChainId=0,this.headJointKey=x,this.jointCount=0,this.islandId=0,this.islandPrev=0,this.islandNext=0,this.sleepThreshold=0,this.sleepTime=0,this.bodyMoveIndex=0,this.id=x,this.type=tt.b2_staticBody,this.revision=0,this.enableSleep=!1,this.fixedRotation=!1,this.isSpeedCapped=!1,this.isMarked=!1,this.updateBodyMass=!1}},Pt=class{constructor(){this.linearVelocity=new g(0,0),this.angularVelocity=0,this.flags=0,this.deltaPosition=new g(0,0),this.deltaRotation=new rt(1,0)}},Hs=class{constructor(){this.transform=new at,this.center=new g(0,0),this.rotation0=new rt(1,0),this.center0X=0,this.center0Y=0,this.localCenter=new g(0,0),this.force=new g(0,0),this.torque=0,this.mass=0,this.invMass=0,this.inertia=0,this.invInertia=0,this.minExtent=0,this.maxExtent=0,this.linearDamping=0,this.angularDamping=0,this.gravityScale=0,this.bodyId=0,this.isFast=!1,this.isBullet=!1,this.isSpeedCapped=!1,this.allowFastRotation=!1,this.enlargeAABB=!1}copyTo(e){e.transform=this.transform.deepClone(),e.center=this.center.clone(),e.rotation0=this.rotation0.clone(),e.center0X=this.center0X,e.center0Y=this.center0Y,e.localCenter=this.localCenter.clone(),e.force=this.force.clone(),e.torque=this.torque,e.mass=this.mass,e.invMass=this.invMass,e.inertia=this.inertia,e.invInertia=this.invInertia,e.minExtent=this.minExtent,e.maxExtent=this.maxExtent,e.linearDamping=this.linearDamping,e.angularDamping=this.angularDamping,e.gravityScale=this.gravityScale,e.bodyId=this.bodyId,e.isFast=this.isFast,e.isBullet=this.isBullet,e.isSpeedCapped=this.isSpeedCapped,e.allowFastRotation=this.allowFastRotation,e.enlargeAABB=this.enlargeAABB}};var Co=16,Es=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Nr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},ln=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},Wr=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}},dn=class{constructor(e=0){this.data=[],this.count=0,this.capacity=e}};function il(t){let e=new Es(t);return t>0?(e.data=po(t,()=>new Hs),e):(e.data=null,e)}function al(t){let e=new ln(t);return t>0?(e.data=po(t,()=>new Qn),e):(e.data=null,e)}function cl(t){let e=new dn(t);return t>0?(e.data=po(t,()=>new Ws),e):(e.data=null,e)}function mn(t){if(t.capacity===0)t.data=po(Co,()=>new Hs),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Hs),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function js(t){if(t.capacity===0)t.data=po(Co,()=>new Pt),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Pt),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function Xe(t){if(t.capacity===0)t.data=po(Co,()=>new Qn),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=8*t.capacity;kn(t.data,e,()=>new Qn),t.capacity=e}else{let e=t.data[t.count];Wo(e),e._bodyIdA=e._bodyIdB=x}return t.count+=1,t.data[t.count-1]}function oo(t){if(t.capacity===0)t.data=po(Co,()=>new Ws),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Ws),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1]}function On(t){if(t.capacity===0)t.data=po(Co,()=>new Os),t.capacity=Co,t.count=0;else if(t.count===t.capacity){let e=2*t.capacity;kn(t.data,e,()=>new Os),t.capacity=e}else Wo(t.data[t.count]);return t.count+=1,t.data[t.count-1].islandId=x,t.data[t.count-1]}function ci(t,e){if(e(t&255)<<8|e&255,Dt=new at(new g,new rt),hu=new at(new g,new rt),pt=new g,bt=new g,Kt=new g,Zt=new g;function Su(t,e,o){let n=J(e,t),s=lt(n),r=be(s),i=new ge;return i.vertices=[t,e],i.centroid=$t(t,e,.5),i.normals=[r,Ht(r)],i.count=2,i.radius=o,i}function li(t,e,o,n,s){Uo(e,n,Dt);let r=t.center,i=Dt.q.c*o.center.x-Dt.q.s*o.center.y+Dt.p.x,c=Dt.q.s*o.center.x+Dt.q.c*o.center.y+Dt.p.y,a=i-r.x,l=c-r.y,d=Math.sqrt(a*a+l*l),p=0,b=0;d>=Xt&&(p=a/d,b=l/d);let u=t.radius,h=o.radius,m=d-u-h;if(m>Qt)return s.clear();let f=r.x+u*p,y=r.y+u*b,I=i+-h*p,C=c+-h*b,_=f+.5*(I-f),S=y+.5*(C-y);s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b,s.normalX=e.q.c*p-e.q.s*b,s.normalY=e.q.s*p+e.q.c*b;let A=s.points[0];return A.anchorAX=e.q.c*_-e.q.s*S,A.anchorAY=e.q.s*_+e.q.c*S,A.anchorBX=A.anchorAX+(e.p.x-n.p.x),A.anchorBY=A.anchorAY+(e.p.y-n.p.y),A.pointX=e.p.x+A.anchorAX,A.pointY=e.p.y+A.anchorAY,A.separation=m,A.id=0,s.pointCount=1,s}function $s(t,e,o,n,s){Uo(e,n,Dt);let r=H(Dt,o.center),i=t.center1,c=t.center2,a=J(c,i),l,d=j(J(r,i),a),p=j(J(c,r),a);if(d<0)l=i;else if(p<0)l=c;else{let A=d/j(a,a);l=$(i,A,a)}let b=Ye(J(r,l)),u=b.length,h=b.normal,m=t.radius,f=o.radius,y=u-m-f;if(y>Qt)return s.clear();let I=$(l,m,h),C=$(r,-f,h),_=$t(I,C,.5);s.normalX=e.q.c*h.x-e.q.s*h.y,s.normalY=e.q.s*h.x+e.q.c*h.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}var Vt=new g;function di(t,e,o,n,s){let r=Qt;Uo(e,n,Dt),Se(Dt,o.center,Vt);let i=t.radius,c=o.radius,a=i+c,l=0,d=-Number.MAX_VALUE,p=t.count,b=t.vertices,u=t.normals;for(let _=0;_d&&(d=S,l=_)}if(d>a+r)return s.clear();let h=l,m=h+1Xt){let _=Vt.x-f.x,S=Vt.y-f.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-f.x)*B+(Vt.y-f.y)*w,d>a+r)return s.clear();let D=f.x+i*B,v=f.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else if(C<0&&d>Xt){let _=Vt.x-y.x,S=Vt.y-y.y,A=Math.sqrt(_*_+S*S),B=0,w=0;if(A>Xt){let E=1/A;B=_*E,w=S*E}if(d=(Vt.x-y.x)*B+(Vt.y-y.y)*w,d>a+r)return s.clear();let D=y.x+i*B,v=y.y+i*w,P=Vt.x-c*B,T=Vt.y-c*w,R=.5*(D+P),X=.5*(v+T);s.normalX=e.q.c*B-e.q.s*w,s.normalY=e.q.s*B+e.q.c*w;let F=s.points[0];F.anchorAX=e.q.c*R-e.q.s*X,F.anchorAY=e.q.s*R+e.q.c*X,F.anchorBX=F.anchorAX+(e.p.x-n.p.x),F.anchorBY=F.anchorAY+(e.p.y-n.p.y),F.pointX=e.p.x+F.anchorAX,F.pointY=e.p.y+F.anchorAY,F.separation=(P-D)*B+(T-v)*w,F.id=0,s.pointCount=1}else{let _=u[l].x,S=u[l].y;s.normalX=e.q.c*_-e.q.s*S,s.normalY=e.q.s*_+e.q.c*S;let A=i-((Vt.x-f.x)*_+(Vt.y-f.y)*S),B=Vt.x+A*_,w=Vt.y+A*S,D=Vt.x-c*_,v=Vt.y-c*S,P=(B+D)*.5,T=(w+v)*.5,R=s.points[0];R.anchorAX=e.q.c*P-e.q.s*T,R.anchorAY=e.q.s*P+e.q.c*T,R.anchorBX=R.anchorAX+(e.p.x-n.p.x),R.anchorBY=R.anchorAY+(e.p.y-n.p.y),R.pointX=e.p.x+R.anchorAX,R.pointY=e.p.y+R.anchorAY,R.separation=d-a,R.id=0,s.pointCount=1}return s}function Qs(t,e,o,n,s){let r=t.center1;vi(e.p,1,K(e.q,r),hu.p),hu.q=e.q,Uo(hu,n,Dt),pt.x=0,pt.y=0,Kt.x=t.center2.x-r.x,Kt.y=t.center2.y-r.y,Se(Dt,o.center1,bt),Se(Dt,o.center2,Zt);let i=Kt.x,c=Kt.y,a=Zt.x-bt.x,l=Zt.y-bt.y,d=i*i+c*c,p=a*a+l*l,b=pt.x-bt.x,u=pt.y-bt.y,h=b*i+u*c,m=b*a+u*l,f=i*a+c*l,y=d*p-f*f,I=0;y!==0&&(I=ht((f*m-h*p)/y,0,1));let C=(f*I+m)/p;C<0?(C=0,I=ht(-h/d,0,1)):C>1&&(C=1,I=ht((f-h)/d,0,1));let _={x:pt.x+I*i,y:pt.y+I*c},S={x:bt.x+C*a,y:bt.y+C*l},A=ue(_,S),B=t.radius,w=o.radius,D=B+w,v=D+Qt;if(A>v*v){Wo(s);return}let P=Math.sqrt(A),T=Da(i,c),R=i*1/T,X=c*1/T,F=Da(a,l),E=a*1/F,W=l*1/F,et=(bt.x-pt.x)*R+(bt.y-pt.y)*X,st=(Zt.x-pt.x)*R+(Zt.y-pt.y)*X,ot=et<=0&&st<=0||et>=T&&st>=T,L=(pt.x-bt.x)*R+(pt.y-bt.y)*W,nt=(Kt.x-bt.x)*R+(Kt.y-bt.y)*W,Ct=L<=0&&nt<=0||L>=F&&nt>=F;if(s.pointCount=0,ot===!1&&Ct===!1){let N,Q,wt;{N=-X,Q=R;let dt=(bt.x-pt.x)*N+(bt.y-pt.y)*Q,Et=(Zt.x-pt.x)*N+(Zt.y-pt.y)*Q,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?wt=Ft:(wt=Jt,N=-N,Q=-Q)}let ct,At,Tt;{ct=-W,At=E;let dt=(pt.x-bt.x)*ct+(pt.y-bt.y)*At,Et=(Kt.x-bt.x)*ct+(Kt.y-bt.y)*At,Ft=Math.min(dt,Et),Jt=Math.max(-dt,-Et);Ft>Jt?Tt=Ft:(Tt=Jt,ct=-ct,At=-At)}if(wt>=Tt){s.normalX=N,s.normalY=Q;let dt=bt.x,Et=bt.y,Ft=Zt.x,Jt=Zt.y;if(et<0&&st>0){let ut=(0-et)/(st-et);dt=bt.x+ut*(Zt.x-bt.x),Et=bt.y+ut*(Zt.y-bt.y)}else if(st<0&&et>0){let ut=(0-st)/(et-st);Ft=Zt.x+ut*(bt.x-Zt.x),Jt=Zt.y+ut*(bt.y-Zt.y)}if(et>T&&stT&&et0){let ut=(0-L)/(nt-L);dt=pt.x+ut*(Kt.x-pt.x),Et=pt.y+ut*(Kt.y-pt.y)}else if(nt<0&&L>0){let ut=(0-nt)/(L-nt);Ft=Kt.x+ut*(pt.x-Kt.x),Jt=Kt.y+ut*(pt.y-Kt.y)}if(L>F&&ntF&&Lwn){let Jt=Math.sqrt(wt);N/=Jt,Q/=Jt}else N=-X,Q=R;let ct=_.x+B*N,At=_.y+B*Q,Tt=S.x-w*N,dt=S.y-w*Q,Et=I===0?0:1,Ft=C===0?0:1;s.normalX=N,s.normalY=Q,s.points[0].anchorAX=(ct+Tt)*.5,s.points[0].anchorAY=(At+dt)*.5,s.points[0].separation=Math.sqrt(A)-D,s.points[0].id=ee(Et,Ft),s.pointCount=1}if(s.pointCount>0){let N=e.q.c*s.normalX-e.q.s*s.normalY,Q=e.q.s*s.normalX+e.q.c*s.normalY;s.normalX=N,s.normalY=Q;for(let wt=0;wtXt?D=$t(f,m,(C-w)/(B-w)):D=f;let v;B>A&&B-w>Xt?v=$t(f,m,(A-w)/(B-w)):v=m;let P=Ma(D,u,b),T=Ma(v,u,b),R=i.radius,X=l.radius;vi(D,.5*(R-X-P),b,pt),vi(v,.5*(R-X-T),b,bt);let F=R+X;if(s===!1){r.normalX=b.x,r.normalY=b.y;let E=r.points[0];E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(c,p),E=r.points[1],E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(a,d),r.pointCount=2}else{r.normalX=-b.x,r.normalY=-b.y;let E=r.points[0];E.anchorAX=bt.x,E.anchorAY=bt.y,E.separation=T-F,E.id=ee(d,a),E=r.points[1],E.anchorAX=pt.x,E.anchorAY=pt.y,E.separation=P-F,E.id=ee(p,c),r.pointCount=2}return r}function kh(t,e){let o=t.count,n=e.count,s=t.normals,r=t.vertices,i=e.vertices,c=0,a=Number.NEGATIVE_INFINITY;for(let l=0;la&&(a=u,c=l)}return{edgeIndex:c,maxSeparation:a}}var kt=new ge(Ce),Ut=new ge(Ce),mu=new g,yu=new at;function Zn(t,e,o,n,s){let r=t.vertices[0].x,i=t.vertices[0].y;mu.x=e.p.x+(e.q.c*r-e.q.s*i),mu.y=e.p.y+(e.q.s*r+e.q.c*i),yu.p=mu,yu.q=e.q,Uo(yu,n,Dt),kt.centroid=null,kt.count=t.count,kt.radius=t.radius,kt.vertices[0].x=0,kt.vertices[0].y=0,kt.normals[0].x=t.normals[0].x,kt.normals[0].y=t.normals[0].y;for(let m=1;mQt+u||b>Qt+u)return s.clear();let h;if(l>=b){h=!1;let m=kt.normals[a],f=Ut.count,y=Ut.normals;p=0;let I=Number.MAX_VALUE;for(let C=0;C.1*It||b>.1*It){let m=a,f=a+1Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=s.points[0];E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,y),s.pointCount=1}else if(B.fraction1===0&&B.fraction2===1){let w=A.x-C.x,D=A.y-C.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=C.x+kt.radius*w,R=C.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(m,I),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===0){let w=S.x-_.x,D=S.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=S.x-Ut.radius*w,F=S.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,y),s.points[0]=E,s.pointCount=1}else if(B.fraction1===1&&B.fraction2===1){let w=A.x-_.x,D=A.y-_.y,v=Math.sqrt(B.distanceSquared);if(v>Qt+u)return s.clear();let P=1/v;w*=P,D*=P;let T=_.x+kt.radius*w,R=_.y+kt.radius*D,X=A.x-Ut.radius*w,F=A.y-Ut.radius*D;s.normalX=w,s.normalY=D;let E=new ko;E.anchorAX=(T+X)*.5,E.anchorAY=(R+F)*.5,E.separation=v-u,E.id=ee(f,I),s.points[0]=E,s.pointCount=1}else Ph(kt,Ut,a,p,h,s)}else Ph(kt,Ut,a,p,h,s);if(s.pointCount>0){let m=s.normalX;s.normalX=e.q.c*s.normalX-e.q.s*s.normalY,s.normalY=e.q.s*m+e.q.c*s.normalY;for(let f=0;f0)return s.clear();b=c}else{let A=j(a,a);b=new g(d*i.x+p*c.x,d*i.y+p*c.y),b=A>0?it(1/A,b):i}let u=Ye(J(r,b)),h=u.length,m=u.normal,f=o.radius,y=h-f;if(y>Qt)return s.clear();let I=b,C=$(r,-f,m),_=$t(I,C,.5);s.normalX=e.q.c*m.x-e.q.s*m.y,s.normalY=e.q.s*m.x+e.q.c*m.y;let S=s.points[0];return S.anchorAX=e.q.c*_.x-e.q.s*_.y,S.anchorAY=e.q.s*_.x+e.q.c*_.y,S.anchorBX=S.anchorAX+(e.p.x-n.p.x),S.anchorBY=S.anchorAY+(e.p.y-n.p.y),S.pointX=e.p.x+S.anchorAX,S.pointY=e.p.y+S.anchorAY,S.separation=y,S.id=0,s.pointCount=1,s}function yi(t,e,o,n,s,r){let i=Su(o.center1,o.center2,o.radius);return Zs(t,e,i,n,s,r)}function fu(t,e,o,n,s,r,i,c,a,l){let d=de(s),p=0,b=j(J(e,t),d),u=j(J(o,t),d),h=j(J(n,t),d);if(uXt?m=$t(n,o,(p-h)/(u-h)):m=n;let f;u>b&&u-h>Xt?f=$t(n,o,(b-h)/(u-h)):f=o;let y=j(J(m,t),s),I=j(J(f,t),s);m=$(m,.5*(r-i-y),s),f=$(f,.5*(r-i-I),s);let C=r+i;l.normalX=s.x,l.normalY=s.y;let _=l.points[0];_.anchorAX=m.x,_.anchorAY=m.y,_.separation=y-C,_.id=c;let S=l.points[1];return S.anchorAX=f.x,S.anchorAY=f.y,S.separation=I-C,S.id=a,l.pointCount=2,l}var ro={b2_normalSkip:0,b2_normalAdmit:1,b2_normalSnap:2};function xu(t,e){return j(e,t.edge1)<=0?t.convex1?z(e,t.normal0)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap:t.convex2?z(t.normal2,e)>.01?ro.b2_normalSkip:ro.b2_normalAdmit:ro.b2_normalSnap}var Iu=class{constructor(){this.edge1=new g,this.normal0=new g,this.normal2=new g,this.convex1=!1,this.convex2=!1}};function Zs(t,e,o,n,s,r){Uo(e,n,Dt);let i=H(Dt,o.centroid),c=o.radius,a=t.segment.point1,l=t.segment.point2,d=lt(J(l,a)),p=new Iu;p.edge1=d.clone();let b=.01,u=lt(J(a,t.ghost1));p.normal0=be(u),p.convex1=z(u,d)>=b;let h=lt(J(t.ghost2,l));p.normal2=be(h),p.convex2=z(d,h)>=b;let m=be(d),f=j(m,J(i,a))<0,y=!0,I=!0;if(p.convex1&&(y=j(p.normal0,J(i,a))<0),p.convex2&&(I=j(p.normal2,J(i,l))<0),f&&y&&I)return r.clear();let C=o.count,_=[],S=[];for(let W=0;Wc+Qt)return r.clear();let w=p.convex1?p.normal0:m,D=p.convex2?p.normal2:m,v=-1,P=-1;if(f==!1&&B.distance>.1*It)if(s.count==1){let W=B.pointA,et=B.pointB,st=lt(J(et,W)),ot=xu(p,st);if(ot==ro.b2_normalSkip)return r.clear();if(ot==ro.b2_normalAdmit){r.normalX=e.q.c*st.x-e.q.s*st.y,r.normalY=e.q.s*st.x+e.q.c*st.y;let L=new ko;return L.anchorAX=e.q.c*W.x-e.q.s*W.y,L.anchorAY=e.q.s*W.x+e.q.c*W.y,L.anchorBX=L.anchorAX+(e.p.x-n.p.x),L.anchorBY=L.anchorAY+(e.p.y-n.p.y),L.pointX=e.p.x+L.anchorAX,L.pointY=e.p.y+L.anchorAY,L.separation=B.distance-c,L.id=ee(s.indexA[0],s.indexB[0]),r.points[0]=L,r.pointCount=1,r}v=s.indexB[0]}else{let W=s.indexA[0],et=s.indexA[1],st=s.indexB[0],ot=s.indexB[1];if(W==et){let L=J(B.pointA,B.pointB),nt=j(L,S[st]),Ct=j(L,S[ot]),N=nt>Ct?st:ot;L=S[N];let Q=xu(p,Ht(L));if(Q==ro.b2_normalSkip)return r.clear();if(Q==ro.b2_normalAdmit){st=N,ot=NW&&(W=ot,v=-1)}if(p.convex2){let ot=Number.MAX_VALUE;for(let L=0;LW&&(W=ot,v=-1)}let et=-Number.MAX_VALUE,st=-1;for(let ot=0;otet&&(et=N,st=ot)}if(et>W){let ot=st,L=ot0?W-1:C-1,st=j(m,S[et]),ot=j(m,S[W]);stArray(Y.b2_shapeTypeCount).fill().map(()=>new gu)),Th=!1;function Nm(t,e,o,n,s,r){return li(t.circle,e,o.circle,n,r)}function Wm(t,e,o,n,s,r){return $s(t.capsule,e,o.circle,n,r)}function Om(t,e,o,n,s,r){return Qs(t.capsule,e,o.capsule,n,r)}function Um(t,e,o,n,s,r){return di(t.polygon,e,o.circle,n,r)}function zm(t,e,o,n,s,r){return pi(t.polygon,e,o.capsule,n,r)}function Km(t,e,o,n,s,r){return Zn(t.polygon,e,o.polygon,n,r)}function Hm(t,e,o,n,s,r){return ui(t.segment,e,o.circle,n,r)}function $m(t,e,o,n,s,r){return bi(t.segment,e,o.capsule,n,r)}function Qm(t,e,o,n,s,r){return hi(t.segment,e,o.polygon,n,r)}function Zm(t,e,o,n,s,r){return mi(t.chainSegment,e,o.circle,n,r)}function ty(t,e,o,n,s,r){return yi(t.chainSegment,e,o.capsule,n,s,r)}function ey(t,e,o,n,s,r){return Zs(t.chainSegment,e,o.polygon,n,s,r)}function Ve(t,e,o){Bn[e][o].fcn=t,Bn[e][o].primary=!0,e!=o&&(Bn[o][e].fcn=t,Bn[o][e].primary=!1)}function Bu(){Th===!1&&(Ve(Nm,Y.b2_circleShape,Y.b2_circleShape),Ve(Wm,Y.b2_capsuleShape,Y.b2_circleShape),Ve(Om,Y.b2_capsuleShape,Y.b2_capsuleShape),Ve(Um,Y.b2_polygonShape,Y.b2_circleShape),Ve(zm,Y.b2_polygonShape,Y.b2_capsuleShape),Ve(Km,Y.b2_polygonShape,Y.b2_polygonShape),Ve(Hm,Y.b2_segmentShape,Y.b2_circleShape),Ve($m,Y.b2_segmentShape,Y.b2_capsuleShape),Ve(Qm,Y.b2_segmentShape,Y.b2_polygonShape),Ve(Zm,Y.b2_chainSegmentShape,Y.b2_circleShape),Ve(ty,Y.b2_chainSegmentShape,Y.b2_capsuleShape),Ve(ey,Y.b2_chainSegmentShape,Y.b2_polygonShape),Th=!0)}function Ba(t,e,o){let n=e.type,s=o.type;if(Bn[n][s].fcn===null)return;if(Bn[n][s].primary===!1){Ba(t,o,e);return}let r=_t(t,e.bodyId),i=_t(t,o.bodyId),c;r.setIndex===M.b2_awakeSet||i.setIndex===M.b2_awakeSet?c=M.b2_awakeSet:c=M.b2_disabledSet;let a=t.solverSetArray[c],l=ne(t.contactIdPool);for(;t.contactArray.length<=l;)t.contactArray.push(new tr);let d=e.id,p=o.id,b=t.contactArray[l];b.contactId=l,b.setIndex=c,b.colorIndex=x,b.localIndex=a.contacts.count,b.islandId=x,b.islandPrev=x,b.islandNext=x,b.shapeIdA=d,b.shapeIdB=p,b.isMarked=!1,b.flags=0,(e.isSensor||o.isSensor)&&(b.flags|=mt.b2_contactSensorFlag),(e.enableSensorEvents||o.enableSensorEvents)&&(b.flags|=mt.b2_contactEnableSensorEvents),(e.enableContactEvents||o.enableContactEvents)&&(b.flags|=mt.b2_contactEnableContactEvents);{b.edges[0].bodyId=e.bodyId,b.edges[0].prevKey=x,b.edges[0].nextKey=r.headContactKey;let m=l<<1|0,f=r.headContactKey;if(f!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}r.headContactKey=m,r.contactCount+=1}{b.edges[1].bodyId=o.bodyId,b.edges[1].prevKey=x,b.edges[1].nextKey=i.headContactKey;let m=l<<1|1,f=i.headContactKey;if(i.headContactKey!==x){let y=t.contactArray[f>>1];y.edges[f&1].prevKey=m}i.headContactKey=m,i.contactCount+=1}let u=cr(d,p);ir(t.broadPhase.pairSet,u);let h=Xe(a.contacts);h.contactId=l,h._bodyIdA=e.bodyId,h._bodyIdB=o.bodyId,h.bodySimIndexA=x,h.bodySimIndexB=x,h.invMassA=0,h.invIA=0,h.invMassB=0,h.invIB=0,h.shapeIdA=d,h.shapeIdB=p,h.friction=Vm(e.friction,o.friction),h.restitution=Ym(e.restitution,o.restitution),h.tangentSpeed=0,h.simFlags=0,(e.enablePreSolveEvents||o.enablePreSolveEvents)&&(h.simFlags|=Nt.b2_simEnablePreSolveEvents)}function xo(t,e,o){let n=cr(e.shapeIdA,e.shapeIdB);ar(t.broadPhase.pairSet,n);let s=e.edges[0],r=e.edges[1],i=s.bodyId,c=r.bodyId,a=_t(t,i),l=_t(t,c),d=e.flags;if(d&(mt.b2_contactTouchingFlag|mt.b2_contactSensorTouchingFlag)&&d&(mt.b2_contactEnableContactEvents|mt.b2_contactEnableSensorEvents)){let h=t.worldId,m=t.shapeArray[e.shapeIdA],f=t.shapeArray[e.shapeIdB],y=new St(m.id+1,h,m.revision),I=new St(f.id+1,h,f.revision);if(d&mt.b2_contactTouchingFlag&&d&mt.b2_contactEnableContactEvents){let C=new Rn(y,I);t.contactEndArray.push(C)}if(d&mt.b2_contactSensorTouchingFlag&&d&mt.b2_contactEnableSensorEvents){let C=new Tn;m.isSensor?(C.sensorShapeId=y,C.visitorShapeId=I):(C.sensorShapeId=I,C.visitorShapeId=y),t.sensorEndEventArray.push(C)}}if(s.prevKey!==x){let m=t.contactArray[s.prevKey>>1].edges[s.prevKey&1];m.nextKey=s.nextKey}if(s.nextKey!==x){let m=t.contactArray[s.nextKey>>1].edges[s.nextKey&1];m.prevKey=s.prevKey}let p=e.contactId,b=p<<1|0;if(a.headContactKey===b&&(a.headContactKey=s.nextKey),a.contactCount-=1,r.prevKey!==x){let m=t.contactArray[r.prevKey>>1].edges[r.prevKey&1];m.nextKey=r.nextKey}if(r.nextKey!==x){let m=t.contactArray[r.nextKey>>1].edges[r.nextKey&1];m.prevKey=r.prevKey}let u=p<<1|1;if(l.headContactKey===u&&(l.headContactKey=r.nextKey),l.contactCount-=1,e.islandId!==x&&ri(t,e),e.colorIndex!==x)kr(t,i,c,e.colorIndex,e.localIndex);else{let h=t.solverSetArray[e.setIndex];if(no(h.contacts,e.localIndex)!==x){let f=h.contacts.data[e.localIndex];t.contactArray[f.contactId].localIndex=e.localIndex}}e.contactId=x,e.setIndex=x,e.colorIndex=x,e.localIndex=x,xe(t.contactIdPool,p),o&&(Ot(t,a),Ot(t,l))}function Yn(t,e){return e.setIndex===M.b2_awakeSet&&e.colorIndex!==x?t.constraintGraph.colors[e.colorIndex].contacts.data[e.localIndex]:t.solverSetArray[e.setIndex].contacts.data[e.localIndex]}function Kr(t,e){return t.groupIndex===e.groupIndex&&t.groupIndex!==0?t.groupIndex>0:(t.maskBits&e.categoryBits)!==0&&(t.categoryBits&e.maskBits)!==0}function oy(t,e,o,n,s){let r=new he;return r.proxyA=$e(t),r.proxyB=$e(o),r.transformA=e,r.transformB=n,r.useRadii=!0,Be(s,r,null,0).distance<10*Xt}var _u=new To;function Au(t,e,o,n,s,r,i,c){let a;if(o.isSensor||r.isSensor)a=oy(o,n,r,i,e.cache);else{e.manifold.copyTo(_u);let l=Bn[o.type][r.type].fcn;l(o,n,r,i,e.cache,e.manifold);let d=e.manifold.pointCount;if(a=d>0,a&&t.preSolveFcn&&e.simFlags&Nt.b2_simEnablePreSolveEvents){let p=new St(o.id+1,t.worldId,o.revision),b=new St(r.id+1,t.worldId,r.revision);a=t.preSolveFcn(p,b,e.manifold,t.preSolveContext),a==!1&&(e.manifold.pointCount=0)}a&&(o.enableHitEvents||r.enableHitEvents)?e.simFlags|=Nt.b2_simEnableHitEvent:e.simFlags&=~Nt.b2_simEnableHitEvent;for(let p=0;pnew hn),this.moveSet=null,this.moveArray=null,this.moveResults=null,this.movePairs=null,this.movePairCapacity=0,this.movePairIndex=0,this.pairSet=null}},qo=t=>t&3,xn=t=>t>>2,Ju=(t,e)=>t<<2|e;function In(t,e){ir(t.moveSet,e+1)||t.moveArray.push(e)}function Mu(t){t.moveSet=Gi(),t.moveArray=[],t.moveResults=null,t.movePairs=null,t.movePairCapacity=0,t.movePairIndex=0,t.pairSet=Gi();for(let e=0;edelete t[e])}function ny(t,e){if(ar(t.moveSet,e+1)){let n=t.moveArray.length;for(let s=0;snew wu),sy(0,o,t);let s=t.shapeArray;for(let r of e.moveResults)for(let i=r.pairList;i;i=i.next)Ba(t,s[i.shapeIndexA],s[i.shapeIndexB]);e.moveArray.length=0,Ea(e.moveSet),Ke(n,e.moveResults),e.moveResults=null,Lt(t)}function sy(t,e,o){let n=o.broadPhase,s=new vu;s.world=o;for(let r=t;r0?(s.inv_dt=1/e,s.h=e/s.subStepCount,s.inv_h=s.subStepCount*s.inv_dt):(s.inv_dt=0,s.h=0,s.inv_h=0),n.inv_h=s.inv_h;let r=Math.min(n.contactHertz,.25*s.inv_h),i=Math.min(n.jointHertz,.125*s.inv_h);s.contactSoftness=ie(r,n.contactDampingRatio,s.h),s.staticSoftness=ie(2*r,n.contactDampingRatio,s.h),s.jointSoftness=ie(i,n.jointDampingRatio,s.h),s.restitutionThreshold=n.restitutionThreshold,s.maxLinearVelocity=n.maxLinearVelocity,s.enableWarmStarting=n.enableWarmStarting,cy(s),s.dt>0&&ul(n,s),n.locked=!1}var An=new g,ts=new g,ly=new rt,Ru=new at(An,ly);function Lh(t,e,o,n){let s=o.clone();switch(e.type){case Y.b2_capsuleShape:{let r=e.capsule;Se(s,r.center1,An),Se(s,r.center2,ts),e.image?t.DrawImageCapsule(An,ts,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCapsule(An,ts,r.radius,n,t.context)}break;case Y.b2_circleShape:{let r=e.circle;U2(s,r.center,Ru),e.image?t.DrawImageCircle(Ru,r.radius,e,t.context):e.imageNoDebug||t.DrawSolidCircle(Ru,r.radius,n,t.context)}break;case Y.b2_polygonShape:{let r=e.polygon;e.image?t.DrawImagePolygon(s,e,t.context):e.imageNoDebug||t.DrawSolidPolygon(s,r.vertices,r.count,r.radius,n,t.context)}break;case Y.b2_segmentShape:{let r=e.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;case Y.b2_chainSegmentShape:{let r=e.chainSegment.segment;Se(s,r.point1,An),Se(s,r.point2,ts),e.imageNoDebug||t.DrawSegment(An,ts,n,t.context)}break;default:break}}var ju=class{constructor(e,o){this.world=e,this.draw=o}};function dy(t,e,o){let n=o,s=n.world,r=n.draw,i=s.shapeArray[e];if(eo(s.debugBodySet,i.bodyId),r.drawShapes){let c=s.bodyArray[i.bodyId],a=jt(s,c),l;c.setIndex>=M.b2_firstSleepingSet?l=V.b2_colorGray:i.customColor!==0?l=i.customColor:c.type===tt.b2_dynamicBody&&a.mass===0?l=V.b2_colorRed:c.setIndex===M.b2_disabledSet?l=V.b2_colorSlateGray:i.isSensor?l=V.b2_colorWheat:a.isBullet&&c.setIndex===M.b2_awakeSet?l=V.b2_colorTurquoise:c.isSpeedCapped?l=V.b2_colorYellow:a.isFast?l=V.b2_colorSalmon:c.type===tt.b2_staticBody?l=V.b2_colorPaleGreen:c.type===tt.b2_kinematicBody?l=V.b2_colorRoyalBlue:c.setIndex===M.b2_awakeSet?l=V.b2_colorPink:l=V.b2_colorGray,Lh(r,i,a.transform,l)}if(r.drawAABBs){let c=i.fatAABB,a=[new g(c.lowerBoundX,c.lowerBoundY),new g(c.upperBoundX,c.lowerBoundY),new g(c.upperBoundX,c.upperBoundY),new g(c.lowerBoundX,c.upperBoundY)];r.DrawPolygon(a,4,V.b2_colorGold,r.context)}return!0}function by(t,e){let o=1,n=.3,s=V.b2_colorGray3,r=V.b2_colorGreen,i=V.b2_colorBlue,c=V.b2_colorGray9,a=V.b2_colorMagenta,l=V.b2_colorYellow,d=[V.b2_colorRed,V.b2_colorOrange,V.b2_colorYellow,V.b2_colorGreen,V.b2_colorCyan,V.b2_colorBlue,V.b2_colorViolet,V.b2_colorPink,V.b2_colorChocolate,V.b2_colorGoldenrod,V.b2_colorCoral,V.b2_colorBlack],p=fs(t.bodyIdPool);t.debugBodySet=to(t.debugBodySet,p);let b=fs(t.jointIdPool);t.debugJointSet=to(t.debugJointSet,b);let u=fs(t.contactIdPool);t.debugContactSet=to(t.debugContactSet,u);let h=new ju(t,e);for(let y=0;y>1,D=B&1,v=t.jointArray[w];Rh(t.debugJointSet,w)===!1&&(ca(e,t,v),eo(t.debugJointSet,w)),B=v.edges[D].nextKey}}let A=It;if(e.drawContacts&&S.type===tt.b2_dynamicBody&&S.setIndex===M.b2_awakeSet){let B=S.headContactKey;for(;B!==x;){let w=B>>1,D=B&1,v=t.contactArray[w];if(B=v.edges[D].nextKey,!(v.setIndex!==M.b2_awakeSet||v.colorIndex===x)){if(Rh(t.debugContactSet,w)===!1){let T=t.constraintGraph.colors[v.colorIndex].contacts.data[v.localIndex],R=T.manifold.pointCount,X=new g(T.manifold.normalX,T.manifold.normalY);for(let F=0;FA?e.DrawPoint(E.pointX,E.pointY,5,s,e.context):E.persisted===!1?e.DrawPoint(E.pointX,E.pointY,10,r,e.context):E.persisted===!0&&e.DrawPoint(E.pointX,E.pointY,5,i,e.context);if(e.drawContactNormals){let W=new g(E.pointX,E.pointY),et=$(W,n,X);e.DrawSegment(W,et,c,e.context)}else if(e.drawContactImpulses){let W=new g(E.pointX,E.pointY),et=$(W,o*E.normalImpulse,X);e.DrawSegment(W,et,a,e.context);let st=`${(1e3*E.normalImpulse).toFixed(1)}`;e.DrawString(W,st,e.context)}if(e.drawFrictionImpulses){let W=be(X),et=new g(E.pointX,E.pointY),st=$(et,o*E.tangentImpulse,W);e.DrawSegment(et,st,l,e.context);let ot=`${(1e3*E.tangentImpulse).toFixed(1)}`;e.DrawString(et,ot,e.context)}}eo(t.debugContactSet,w)}B=v.edges[D].nextKey}}}I=I&I-1}}}function Vu(t,e){let o=gt(t);if(!o.locked){if(e.useDrawingBounds){by(o,e);return}if(e.drawShapes){let n=o.solverSetArray.length;for(let s=0;s=M.b2_firstSleepingSet?u=V.b2_colorGray:b.customColor!==0?u=b.customColor:l.type===tt.b2_dynamicBody&&a.mass===0?u=V.b2_colorRed:l.setIndex===M.b2_disabledSet?u=V.b2_colorSlateGray:b.isSensor?u=V.b2_colorWheat:a.isBullet&&l.setIndex===M.b2_awakeSet?u=V.b2_colorTurquoise:l.isSpeedCapped?u=V.b2_colorYellow:a.isFast?u=V.b2_colorSalmon:l.type===tt.b2_staticBody?u=V.b2_colorPaleGreen:l.type===tt.b2_kinematicBody?u=V.b2_colorRoyalBlue:l.setIndex===M.b2_awakeSet?u=V.b2_colorPink:u=V.b2_colorGray,Lh(e,b,d,u),p=b.nextShapeId}}}}if(e.drawJoints){let n=o.jointArray.length;for(let s=0;sr?e.DrawPoint(S.pointX,S.pointY,5,i,e.context):S.persisted===!1?e.DrawPoint(S.pointX,S.pointY,10,c,e.context):S.persisted===!0&&e.DrawPoint(S.pointX,S.pointY,5,a,e.context);if(e.drawContactNormals){let A=new g(S.pointX,S.pointY),B=$(A,.3,C);e.DrawSegment(A,B,l,e.context)}else if(e.drawContactImpulses){let A=new g(S.pointX,S.pointY),B=$(A,1*S.normalImpulse,C);e.DrawSegment(A,B,d,e.context);let w=`${(1e3*S.normalImpulse).toFixed(2)}`;e.DrawString(A,w,e.context)}if(e.drawFrictionImpulses){let A=be(C),B=new g(S.pointX,S.pointY),w=$(B,1*S.tangentImpulse,A);e.DrawSegment(B,w,p,e.context);let D=`${S.normalImpulse.toFixed(2)}`;e.DrawString(B,D,e.context)}}}}}}}function Yu(t){let e=gt(t);if(e.locked)return new En;let o=e.bodyMoveEventArray.length,n=new En;return n.moveEvents=e.bodyMoveEventArray,n.moveCount=o,n}function Nu(t){let e=gt(t);if(e.locked)return new Gn;let o=e.sensorBeginEventArray.length,n=e.sensorEndEventArray.length,s=new Gn;return s.beginEvents=e.sensorBeginEventArray,s.endEvents=e.sensorEndEventArray,s.beginCount=o,s.endCount=n,s}function Wu(t){let e=gt(t);if(e.locked)return new Ln;let o=e.contactBeginArray.length,n=e.contactEndArray.length,s=e.contactHitArray.length,r=new Ln;return r.beginEvents=e.contactBeginArray,r.endEvents=e.contactEndArray,r.hitEvents=e.contactHitArray,r.beginCount=o,r.endCount=n,r.hitCount=s,r}function Ou(t){if(t===void 0||t.index1<1||er0&&qe(o,s)}}function Qu(t,e){let o=gt(t);o.locked||(o.enableWarmStarting=e)}function Zu(t,e){let o=gt(t);o.locked||(o.enableContinuous=e)}function t2(t,e){let o=gt(t);o.locked||(o.restitutionThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function e2(t,e){let o=gt(t);o.locked||(o.hitEventThreshold=Math.max(0,Math.min(e,Number.MAX_VALUE)))}function o2(t,e,o,n){let s=gt(t);s.locked||(s.contactHertz=ht(e,0,Number.MAX_VALUE),s.contactDampingRatio=ht(o,0,Number.MAX_VALUE),s.contactPushoutVelocity=ht(n,0,Number.MAX_VALUE))}function py(t,e,o){let n=o,s=n.world,r=s.shapeArray[e],i=r.filter,c=n.filter;if(!(i.categoryBits&c.maskBits)||!(i.maskBits&c.categoryBits))return!0;let a=new St(e+1,s.worldId,r.revision);return n.fcn(a,n.userContext)}var Fu=class{constructor(e=null,o=null,n=null,s=null){this.world=e,this.fcn=o,this.filter=n,this.userContext=s}};function n2(t,e,o,n,s){let r=gt(t);if(r.locked)return;let i=new Fu(r,n,o,s);for(let c=0;c0)return!0;let u=new St(r.id+1,s.worldId,r.revision);return n.fcn(u,n.userContext)}function r2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=jn(e,o),a=new Si;a.world=i,a.fcn=s,a.filter=n,a.proxy=vt(e.center,1,e.radius),a.transform=o,a.userContext=r;for(let l=0;l=0&&u<=1&&(s.fraction=u),u}return t.maxFraction}function c2(t,e,o,n,s,r){let i=gt(t);if(i.locked)return;let c=new Po;c.origin=e,c.translation=o,c.maxFraction=1;let a=new es;a.world=i,a.fcn=s,a.filter=n,a.fraction=1,a.userContext=r;for(let l=0;lH(o,d)),a.count=e.count,a.radius=e.radius,a.translation=n,a.maxFraction=1;let l=new es;l.world=c,l.fcn=r,l.filter=s,l.fraction=1,l.userContext=i;for(let d=0;dn.radius)return!0;let p=d.pointA;if(d.distance===0){let S=Ds(r);p=H(c,S)}let b=.4,u=Qa(r),h=n.magnitude*u*(1-b*d.distance/n.radius),m=lt(J(p,n.position)),f=it(h,m),y=i.localIndex,I=s.solverSetArray[M.b2_awakeSet],C=I.states.data[y],_=I.sims.data[y];return C.linearVelocity=$(C.linearVelocity,_.invMass,f),C.angularVelocity+=_.invInertia*z(J(p,_.center),f),!0}function x2(t,e,o,n){let s=gt(t);if(s.locked)return;let r=new Xu(s,e,o,n),i=new xt(e.x-o,e.y-o,e.x+o,e.y+o);ve(s.broadPhase.trees[tt.b2_dynamicBody],i,Pn,hy,r)}function Lu(t,e){if(e===x)return x;let o=e,n=t.islandArray[e];for(;n.parentIsland!==x;){let s=t.islandArray[n.parentIsland];o=n.parentIsland,n=s}return o}function se(t,e){Array.isArray(t)}function ii(t){if(!uo)return;let e=t.bodyArray.length;for(let o=0;o>1,l=i&1,d=t.contactArray[a];if((d.flags&mt.b2_contactTouchingFlag)!==0&&!(d.flags&mt.b2_contactSensorFlag)&&r!==M.b2_staticSet){let b=Lu(t,d.islandId)}i=d.edges[l].nextKey}let c=n.headJointKey;for(;c!==x;){let a=c>>1,l=c&1,d=t.jointArray[a],p=l^1,b=t.bodyArray[d.edges[p].bodyId];if(!(r===M.b2_disabledSet||b.setIndex===M.b2_disabledSet))if(r===M.b2_staticSet)b.setIndex,M.b2_staticSet;else{let u=Lu(t,d.islandId)}c=d.edges[l].nextKey}}}function Lt(t){if(!uo)return;let e=0,o=0,n=0,s=0,r=0,i=t.solverSetArray.length;for(let b=0;b>1,w=S&1;se(t.contactArray,B),S=t.contactArray[B].edges[w].nextKey}let A=I.headJointKey;for(;A!==x;){let B=A>>1,w=A&1;se(t.jointArray,B);let D=t.jointArray[B],v=w^1;se(t.bodyArray,D.edges[v].bodyId);let P=t.bodyArray[D.edges[v].bodyId];b===M.b2_disabledSet||P.setIndex===M.b2_disabledSet||b===M.b2_staticSet&&P.setIndex===M.b2_staticSet||b===M.b2_awakeSet||b>=M.b2_firstSleepingSet;let T=No(t,D);A=D.edges[w].nextKey}}}{let h=t.contactArray;s+=u.contacts.count;for(let m=0;m=t.blockCount?!1:(t.bits[o]&BigInt(1)<=M.b2_firstSleepingSet;let p=(Yn(t,r).simFlags&Nt.b2_simTouchingFlag)!==0}let n=on(t.contactIdPool)}function Fh(){}function Xh(){}function qh(){}var Tg=new g;var I2=class{constructor(){this.bodyId=null,this.jointId=null,this.frictionScale=1,this.parentIndex=-1,this.name=""}},Aa=class{static HumanBones={e_hip:0,e_torso:1,e_head:2,e_upperLeftLeg:3,e_lowerLeftLeg:4,e_upperRightLeg:5,e_lowerRightLeg:6,e_upperLeftArm:7,e_lowerLeftArm:8,e_upperRightArm:9,e_lowerRightArm:10,e_count:11};static sideViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[0,-.02],center2:[0,.02],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperRightLeg",parentIndex:0,position:[0,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[0,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[0,1.225],capsule:{center1:[0,-.125],center2:[0,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[0,.975],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.25*Math.PI,0]},{boneName:"head",pivot:[0,1.4],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperLeftLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerLeftLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperRightLeg",pivot:[0,.9],limits:[-.05*Math.PI,.4*Math.PI]},{boneName:"lowerRightLeg",pivot:[0,.625],limits:[-.5*Math.PI,-.02*Math.PI]},{boneName:"upperLeftArm",pivot:[0,1.35],limits:[-.1*Math.PI,.8*Math.PI]},{boneName:"lowerLeftArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]},{boneName:"upperRightArm",pivot:[0,1.35],limits:null},{boneName:"lowerRightArm",pivot:[0,1.1],limits:[.01*Math.PI,.5*Math.PI]}]};static frontViewHuman11={BONE_DATA:[{name:"hip",parentIndex:-1,position:[0,.95],capsule:{center1:[-.03,0],center2:[.03,0],radius:.095}},{name:"torso",parentIndex:0,position:[0,1.2],capsule:{center1:[0,-.135],center2:[0,.135],radius:.09},frictionScale:.5},{name:"head",parentIndex:1,position:[0,1.5],capsule:{center1:[0,-.0325],center2:[0,.0325],radius:.08},frictionScale:.25,linearDamping:.1},{name:"upperLeftLeg",parentIndex:0,position:[-.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerLeftLeg",parentIndex:3,position:[-.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"left"},{name:"upperRightLeg",parentIndex:0,position:[.1,.775],capsule:{center1:[0,-.125],center2:[0,.125],radius:.06}},{name:"lowerRightLeg",parentIndex:5,position:[.1,.475],capsule:{center1:[0,-.14],center2:[0,.125],radius:.05},frictionScale:.5,foot:"right"},{name:"upperLeftArm",parentIndex:1,position:[-.15,1.22],capsule:{center1:[0,-.125],center2:[.05,.125],radius:.035},frictionScale:.5},{name:"lowerLeftArm",parentIndex:7,position:[-.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1},{name:"upperRightArm",parentIndex:1,position:[.15,1.22],capsule:{center1:[0,-.125],center2:[-.05,.125],radius:.035},frictionScale:.5},{name:"lowerRightArm",parentIndex:9,position:[.15,.97],capsule:{center1:[0,-.125],center2:[0,.125],radius:.03},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"torso",pivot:[0,1],limits:[-.1*Math.PI,.1*Math.PI]},{boneName:"head",pivot:[0,1.4],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"upperLeftLeg",pivot:[-.1,.9],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"lowerLeftLeg",pivot:[-.1,.625],limits:[0,.5*Math.PI]},{boneName:"upperRightLeg",pivot:[.1,.9],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"lowerRightLeg",pivot:[.1,.625],limits:[-.5*Math.PI,0]},{boneName:"upperLeftArm",pivot:[-.12,1.35],limits:[-.7*Math.PI,.1*Math.PI]},{boneName:"lowerLeftArm",pivot:[-.16,1.1],limits:[0,.75*Math.PI]},{boneName:"upperRightArm",pivot:[.12,1.35],limits:[-.1*Math.PI,.7*Math.PI]},{boneName:"lowerRightArm",pivot:[.14,1.1],limits:[0,.75*Math.PI]}]};static ElephantBones={e_torso:0,e_head:1,e_trunkBase:2,e_trunkMid:3,e_trunkTip:4,e_upperFrontLegL:5,e_lowerFrontLegL:6,e_upperRearLegL:7,e_lowerRearLegL:8,e_tail:9,e_ear:10,e_count:11};static sideViewElephant={BONE_DATA:[{name:"torso",parentIndex:-1,position:[0,1.5],capsule:{center1:[.8,0],center2:[-.8,0],radius:.6},frictionScale:.5},{name:"head",parentIndex:0,position:[-1.4,2.2],capsule:{center1:[.3,0],center2:[-.3,0],radius:.35},frictionScale:.25,linearDamping:.1},{name:"trunkBase",parentIndex:1,position:[-1.95,1.85],capsule:{center1:[0,-.2],center2:[0,.2],radius:.15}},{name:"trunkMid",parentIndex:2,position:[-1.95,1.4],capsule:{center1:[0,-.2],center2:[0,.2],radius:.12}},{name:"trunkTip",parentIndex:3,position:[-1.95,1.05],capsule:{center1:[0,-.2],center2:[0,.2],radius:.08},frictionScale:.1,linearDamping:.1},{name:"upperFrontLeg",parentIndex:0,position:[-.6,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2}},{name:"lowerFrontLeg",parentIndex:5,position:[-.6,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.18},frictionScale:.5},{name:"upperBackLeg",parentIndex:0,position:[.7,.8],capsule:{center1:[0,-.3],center2:[0,.3],radius:.22}},{name:"lowerBackLeg",parentIndex:7,position:[.7,.2],capsule:{center1:[0,-.3],center2:[0,.3],radius:.2},frictionScale:.5},{name:"tail",parentIndex:0,position:[1.2,1.6],capsule:{center1:[0,-.3],center2:[0,.3],radius:.05},frictionScale:.1,linearDamping:.1},{name:"ear",parentIndex:1,position:[-1.1,2],capsule:{center1:[0,-.15],center2:[0,.15],radius:.3},frictionScale:.1,linearDamping:.1}],JOINT_DATA:[{boneName:"head",pivot:[-1,2],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"trunkBase",pivot:[-1.95,2],limits:[-.5*Math.PI,.5*Math.PI]},{boneName:"trunkMid",pivot:[-1.95,1.55],limits:[-.7*Math.PI,.7*Math.PI]},{boneName:"trunkTip",pivot:[-1.95,1.15],limits:[-.9*Math.PI,.9*Math.PI]},{boneName:"upperFrontLeg",pivot:[-.6,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerFrontLeg",pivot:[-.6,.5],limits:[-.3*Math.PI,.1*Math.PI]},{boneName:"upperBackLeg",pivot:[.7,1.1],limits:[-.2*Math.PI,.2*Math.PI]},{boneName:"lowerBackLeg",pivot:[.7,.5],limits:[-.1*Math.PI,.3*Math.PI]},{boneName:"tail",pivot:[1.2,1.9],limits:[-.4*Math.PI,.4*Math.PI]},{boneName:"ear",pivot:[-1.1,2.2],limits:[-.3*Math.PI,.9*Math.PI]}]}},Ca=class{constructor(e,o,n,s,r,i,c=2){this.skeleton=e,this.position=new g(o,n),this.worldId=s,this.groupIndex=r,this.color=i,this.m_scale=c,this.frictionTorque=.05,this.hertz=0,this.dampingRatio=.5,this.jointDrawSize=.5,this.maxTorque=this.frictionTorque*this.m_scale,this.m_bones=[],this.create()}createBone(e){let{bodyId:o}=Ai({worldId:this.worldId,position:U(new g(e.position[0]*this.m_scale,e.position[1]*this.m_scale),this.position),type:tt.b2_dynamicBody,center1:new g(e.capsule.center1[0]*this.m_scale,e.capsule.center1[1]*this.m_scale),center2:new g(e.capsule.center2[0]*this.m_scale,e.capsule.center2[1]*this.m_scale),radius:e.capsule.radius*this.m_scale,density:1,friction:.2,groupIndex:-this.groupIndex,color:this.color}),n=new I2;if(n.name=e.name,n.parentIndex=e.parentIndex,n.frictionScale=e.frictionScale||1,n.bodyId=o,e.foot){let s=fe();s.density=1,s.friction=.2,s.filter.groupIndex=-this.groupIndex,s.filter.maskBits=1,s.customColor=this.color;let r=e.foot=="left"?-1:1,i=new _e;i.center1=new g(r*-.02*this.m_scale,-.175*this.m_scale),i.center2=new g(r*.13*this.m_scale,-.175*this.m_scale),i.radius=.03*this.m_scale,qn(o,s,i)}return n}createJoint(e){let o=this.m_bones.find(i=>i.name===e.boneName),n=this.m_bones[o.parentIndex],s=U(new g(e.pivot[0]*this.m_scale,e.pivot[1]*this.m_scale),this.position),r=new mo;return r.bodyIdA=n.bodyId,r.bodyIdB=o.bodyId,r.localAnchorA=zs(r.bodyIdA,s),r.localAnchorB=zs(r.bodyIdB,s),e.limits&&(r.enableLimit=!0,r.lowerAngle=e.limits[0],r.upperAngle=e.limits[1]),r.enableMotor=!0,r.maxMotorTorque=o.frictionScale*this.maxTorque,r.enableSpring=this.hertz>0,r.hertz=this.hertz,r.dampingRatio=this.dampingRatio,r.drawSize=this.jointDrawSize,Sn(this.worldId,r)}create(){return this.m_bones=this.skeleton.BONE_DATA.map(e=>this.createBone(e)),this.skeleton.JOINT_DATA.forEach(e=>{let o=this.m_bones.find(n=>n.name===e.boneName);o.jointId=this.createJoint(e)}),this.m_bones.forEach(e=>gn(e.bodyId,this)),this}destroy(){for(let e=0;e{_2(e,o)})}function _2(t,e){let o=ai(t.bodyId);e.x=o.p.x*Cn,e.y=-(o.p.y*Cn),e.rotation=-Math.atan2(o.q.s,o.q.c)}function $h(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=B2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Qh(t,e,o){let n=e?.scaleX||e?.scale?.x||1,s=e?.scaleY||e?.scale?.y||1,r={worldId:t,type:S2,size:or(e.width*n/2,e.height*s/2)},i=g2({...r,...o});return Ks(i.bodyId,or(e.x,-e.y),wa(e.rotation)),i}function Zh(t){let e=t.worldDef;return e||(e=lr()),_i(),{worldId:gi(e)}}var Ja=0;function tm(t){let e=t.fixedTimeStep;e||(e=1/60);let o=t.subStepCount;o||(o=4);let n=e*2;Ja=Math.min(Ja+t.deltaTime,e+n);let r=2;t.deltaTime>e&&(r=0);let i=0;for(;Ja>=e&&r-->=0&&iCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s=[],r=2*Math.PI/t.sides;for(let l=0;lCe)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.bodyId;o||(o=Ao(t.worldId,e));let n=t.shapeDef||fe();G(n,"density",t.density),G(n,"friction",t.friction),G(n.filter,"groupIndex",t.groupIndex),G(n,"customColor",t.color);let s,r=nn(t.vertices,t.vertices.length);if(t.bodyId!=null){let c=le(t.worldId,t.bodyId),a=new at(t.position,c.q);s=gs(r,0,a)}else s=sn(r,0);let i=fo(o,n,s);return{bodyId:o,shapeId:i,object:s}}function nm(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=[],s=t.vertexScale;s||(s=new g(1,1));let r=t.vertexOffset;r||(r=new g(0,0));for(let c=0,a=t.indices[0].length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}})}function A2(t){if(t.vertices.length<3)return null;let e=t.bodyDef||Fe();G(e,"type",t.type),G(e,"position",t.position);let o=t.shapeDef||fe();G(o,"density",t.density),G(o,"friction",t.friction),G(o,"restitution",t.restitution),G(o.filter,"groupIndex",t.groupIndex),G(o,"customColor",t.color);let n=t.vertexScale;n||(n=new g(1,1));let s=t.vertexOffset;s||(s=new g(0,0));let r=[];for(let c=0,a=t.indices.length;c{if(!i)i=va({worldId:t.worldId,type:tt.b2_dynamicBody,bodyDef:e,vertices:c,density:1,friction:.3,color:V.b2_colorSkyBlue});else{let a=nn(c,c.length),l=sn(a,0);fo(i.bodyId,o,l)}}),i}function sm(t){let e=t.key,o=t.url;async function n(i){try{let a=await(await fetch(i)).text();return new DOMParser().parseFromString(a,"text/xml")}catch(c){throw c}}function s(i,c){let a=c.querySelectorAll(`body[name=${i}] fixtures polygon`),l=[],d=[];function p(b,u){let m=l.length;for(let f=0;f{let u=b.textContent.trim().split(/[,\s]+/).map(Number),h=[];for(let m=0;m{try{let a=await n(o),l=s(e,a),d=r(l);i(d)}catch(a){c(a)}})}function Ci(t){let e=t.jointDef;return e||(e=new mo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"lowerAngle",t.lowerAngle),G(e,"upperAngle",t.upperAngle),G(e,"enableLimit",t.enableLimit),G(e,"enableMotor",t.enableMotor),G(e,"motorSpeed",t.motorSpeed),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),G(e,"drawSize",t.drawSize),{jointId:Sn(t.worldId,e)}}function rm(t){let e=t.jointDef;e||(e=new tn),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB);let o=Us(t.bodyIdA),n=Us(t.bodyIdB);return e.referenceAngle=oe(n,o),G(e,"referenceAngle",t.referenceAngle),G(e,"angularHertz",t.hertz),G(e,"angularDampingRatio",t.dampingRatio),G(e,"collideConnected",t.collideConnected),{jointId:ei(t.worldId,e)}}function im(t){let e=t.jointDef;return e||(e=new Ho),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"length",t.length),G(e,"minLength",t.minLength),G(e,"maxLength",t.maxLength),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"collideConnected",t.collideConnected),{jointId:$r(t.worldId,e)}}function am(t){let e=t.jointDef;return e||(e=new en),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"enableSpring",t.enableSpring),G(e,"localAxisA",t.axis),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorTorque",t.maxMotorTorque),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:oi(t.worldId,e)}}function cm(t){let e=t.jointDef;return e||(e=new Zo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"localAnchorA",t.anchorA),G(e,"localAnchorB",t.anchorB),G(e,"localAxisA",t.axis),G(e,"referenceAngle",t.referenceAngle),G(e,"enableSpring",t.enableSpring),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"enableLimit",t.enableLimit),G(e,"lowerTranslation",t.lowerTranslation),G(e,"upperTranslation",t.upperTranslation),G(e,"enableMotor",t.enableMotor),G(e,"maxMotorForce",t.maxMotorForce),G(e,"motorSpeed",t.motorSpeed),G(e,"collideConnected",t.collideConnected),{jointId:ti(t.worldId,e)}}function lm(t){let e=t.jointDef;return e||(e=new $o),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"linearOffset",t.linearOffset),G(e,"maxForce",t.maxForce),G(e,"angularOffset",t.angularOffset),G(e,"maxTorque",t.maxTorque),G(e,"correctionFactor",t.correctionFactor),G(e,"collideConnected",t.collideConnected),{jointId:Qr(t.worldId,e)}}function dm(t){let e=t.jointDef;return e||(e=new Qo),e.bodyIdA=t.bodyIdA,e.bodyIdB=t.bodyIdB,G(e,"target",t.target),G(e,"hertz",t.hertz),G(e,"dampingRatio",t.dampingRatio),G(e,"maxForce",t.maxForce),G(e,"collideConnected",t.collideConnected),{jointId:Zr(t.worldId,e)}}var fA=0,xA=1,IA=2;export{Oh as AddSpriteToWorld,bh as B2_ID_EQUALS,dh as B2_IS_NON_NULL,lh as B2_IS_NULL,x as B2_NULL_INDEX,_2 as BodyToSprite,zh as ClearWorldSprites,B2 as CreateBoxPolygon,Ai as CreateCapsule,em as CreateChain,g2 as CreateCircle,im as CreateDistanceJoint,lm as CreateMotorJoint,dm as CreateMouseJoint,om as CreateNGonPolygon,sm as CreatePhysicsEditorShape,va as CreatePolygon,nm as CreatePolygonFromEarcut,A2 as CreatePolygonFromVertices,cm as CreatePrismaticJoint,Ci as CreateRevoluteJoint,rm as CreateWeldJoint,am as CreateWheelJoint,Zh as CreateWorld,IA as DYNAMIC,Kh as GetBodyFromSprite,Yh as GetWorldScale,xA as KINEMATIC,Ca as Ragdoll,Uh as RemoveSpriteFromWorld,wa as RotFromRad,fA as STATIC,Vh as SetWorldScale,Aa as Skeletons,$h as SpriteToBox,Qh as SpriteToCircle,Hh as UpdateWorldSprites,tm as WorldStep,xt as b2AABB,Le as b2AABB_Center,Jo as b2AABB_Contains,rs as b2AABB_Extents,ka as b2AABB_IsValid,qt as b2AABB_Union,nr as b2Abs,D2 as b2AbsFloat,T2 as b2AbsInt,U as b2Add,ps as b2BodyDef,En as b2BodyEvents,Ee as b2BodyId,tt as b2BodyType,Gp as b2Body_ApplyAngularImpulse,Dp as b2Body_ApplyForce,Ia as b2Body_ApplyForceToCenter,kp as b2Body_ApplyLinearImpulse,Tp as b2Body_ApplyLinearImpulseToCenter,Np as b2Body_ApplyMassFromShapes,Pp as b2Body_ApplyTorque,_p as b2Body_ComputeAABB,su as b2Body_Disable,ru as b2Body_Enable,du as b2Body_EnableHitEvents,nu as b2Body_EnableSleep,zp as b2Body_GetAngularDamping,vp as b2Body_GetAngularVelocity,Ip as b2Body_GetContactCapacity,Sp as b2Body_GetContactData,Hp as b2Body_GetGravityScale,pu as b2Body_GetJointCount,uu as b2Body_GetJoints,Op as b2Body_GetLinearDamping,wp as b2Body_GetLinearVelocity,Xp as b2Body_GetLocalCenterOfMass,zs as b2Body_GetLocalPoint,Ap as b2Body_GetLocalVector,jp as b2Body_GetMass,Yp as b2Body_GetMassData,gp as b2Body_GetPosition,Us as b2Body_GetRotation,Fp as b2Body_GetRotationalInertia,bu as b2Body_GetShapeCount,Sa as b2Body_GetShapes,ou as b2Body_GetSleepThreshold,ai as b2Body_GetTransform,Rp as b2Body_GetType,Ep as b2Body_GetUserData,qp as b2Body_GetWorldCenterOfMass,Bp as b2Body_GetWorldPoint,Cp as b2Body_GetWorldVector,$p as b2Body_IsAwake,lu as b2Body_IsBullet,Zp as b2Body_IsEnabled,au as b2Body_IsFixedRotation,tu as b2Body_IsSleepEnabled,Uu as b2Body_IsValid,Up as b2Body_SetAngularDamping,Mp as b2Body_SetAngularVelocity,Qp as b2Body_SetAwake,cu as b2Body_SetBullet,iu as b2Body_SetFixedRotation,Kp as b2Body_SetGravityScale,Wp as b2Body_SetLinearDamping,Jp as b2Body_SetLinearVelocity,Vp as b2Body_SetMassData,eu as b2Body_SetSleepThreshold,Ks as b2Body_SetTransform,Lp as b2Body_SetType,gn as b2Body_SetUserData,_e as b2Capsule,me as b2CastOutput,hs as b2ChainDef,Mo as b2ChainId,Ue as b2ChainSegment,Ku as b2Chain_IsValid,Rc as b2Chain_SetFriction,Lc as b2Chain_SetRestitution,ce as b2Circle,L2 as b2Clamp,ht as b2ClampFloat,G2 as b2ClampInt,$s as b2CollideCapsuleAndCircle,Qs as b2CollideCapsules,yi as b2CollideChainSegmentAndCapsule,mi as b2CollideChainSegmentAndCircle,Zs as b2CollideChainSegmentAndPolygon,li as b2CollideCircles,pi as b2CollidePolygonAndCapsule,di as b2CollidePolygonAndCircle,Zn as b2CollidePolygons,bi as b2CollideSegmentAndCapsule,ui as b2CollideSegmentAndCircle,hi as b2CollideSegmentAndPolygon,X2 as b2ComputeAngularVelocity,Fn as b2ComputeCapsuleAABB,As as b2ComputeCapsuleMass,jn as b2ComputeCircleAABB,Bs as b2ComputeCircleMass,nn as b2ComputeHull,Xn as b2ComputePolygonAABB,Sr as b2ComputePolygonMass,Cs as b2ComputeSegmentAABB,Xi as b2ContactData,Ln as b2ContactEvents,Ao as b2CreateBody,qn as b2CreateCapsuleShape,Ha as b2CreateChain,Ms as b2CreateCircleShape,$r as b2CreateDistanceJoint,Qr as b2CreateMotorJoint,Zr as b2CreateMouseJoint,fo as b2CreatePolygonShape,ti as b2CreatePrismaticJoint,Sn as b2CreateRevoluteJoint,za as b2CreateSegmentShape,nh as b2CreateTimer,ei as b2CreateWeldJoint,oi as b2CreateWheelJoint,gi as b2CreateWorld,_i as b2CreateWorldArray,z as b2Cross,Gt as b2CrossSV,Oo as b2CrossVS,pr as b2DebugDraw,Fe as b2DefaultBodyDef,Va as b2DefaultChainDef,Hb as b2DefaultDistanceJointDef,dr as b2DefaultFilter,$b as b2DefaultMotorJointDef,Qb as b2DefaultMouseJointDef,Zb as b2DefaultPrismaticJointDef,qa as b2DefaultQueryFilter,ia as b2DefaultRevoluteJointDef,fe as b2DefaultShapeDef,tp as b2DefaultWeldJointDef,ep as b2DefaultWheelJointDef,lr as b2DefaultWorldDef,_n as b2DestroyBody,$a as b2DestroyChain,ni as b2DestroyJoint,Ka as b2DestroyShape,qu as b2DestroyWorld,os as b2Distance,ye as b2DistanceCache,he as b2DistanceInput,Ho as b2DistanceJointDef,Il as b2DistanceJoint_EnableLimit,Pl as b2DistanceJoint_EnableMotor,Cl as b2DistanceJoint_EnableSpring,Al as b2DistanceJoint_GetCurrentLength,xl as b2DistanceJoint_GetLength,Bl as b2DistanceJoint_GetMaxLength,El as b2DistanceJoint_GetMaxMotorForce,gl as b2DistanceJoint_GetMinLength,Rl as b2DistanceJoint_GetMotorForce,Gl as b2DistanceJoint_GetMotorSpeed,Dl as b2DistanceJoint_GetSpringDampingRatio,Ml as b2DistanceJoint_GetSpringHertz,Sl as b2DistanceJoint_IsLimitEnabled,kl as b2DistanceJoint_IsMotorEnabled,wl as b2DistanceJoint_IsSpringEnabled,fl as b2DistanceJoint_SetLength,_l as b2DistanceJoint_SetLengthRange,Ll as b2DistanceJoint_SetMaxMotorForce,Tl as b2DistanceJoint_SetMotorSpeed,Jl as b2DistanceJoint_SetSpringDampingRatio,vl as b2DistanceJoint_SetSpringHertz,as as b2DistanceOutput,Pe as b2DistanceProxy,ue as b2DistanceSquared,j as b2Dot,hn as b2DynamicTree,Er as b2DynamicTree_Create,Fr as b2DynamicTree_CreateProxy,jr as b2DynamicTree_Destroy,Xr as b2DynamicTree_DestroyProxy,un as b2DynamicTree_EnlargeProxy,Qc as b2DynamicTree_GetAreaRatio,nl as b2DynamicTree_GetByteCount,$c as b2DynamicTree_GetHeight,tl as b2DynamicTree_GetMaxBalance,Hc as b2DynamicTree_GetProxyCount,qr as b2DynamicTree_MoveProxy,ve as b2DynamicTree_Query,Gs as b2DynamicTree_RayCast,Rs as b2DynamicTree_Rebuild,el as b2DynamicTree_RebuildBottomUp,Nn as b2DynamicTree_ShapeCast,ol as b2DynamicTree_ShiftOrigin,Zc as b2DynamicTree_Validate,ho as b2Filter,oh as b2GetByteCount,ss as b2GetInverse22,Ye as b2GetLengthAndNormalize,Ga as b2GetLengthUnitsPerMeter,rh as b2GetMilliseconds,ih as b2GetMillisecondsAndReset,we as b2GetSweepTransform,sh as b2GetTicks,La as b2GetVersion,V as b2HexColor,Jn as b2Hull,j2 as b2IntegrateRotation,O2 as b2InvMulRot,ki as b2InvMulTransforms,Ie as b2InvRotateVector,Re as b2InvTransformPoint,wi as b2IsNormalized,ae as b2IsValid,Na as b2IsValidRay,zt as b2JointId,k as b2JointType,np as b2Joint_GetBodyA,sp as b2Joint_GetBodyB,cp as b2Joint_GetCollideConnected,bp as b2Joint_GetConstraintForce,pp as b2Joint_GetConstraintTorque,rp as b2Joint_GetLocalAnchorA,ip as b2Joint_GetLocalAnchorB,op as b2Joint_GetType,dp as b2Joint_GetUserData,Hu as b2Joint_IsValid,ap as b2Joint_SetCollideConnected,lp as b2Joint_SetUserData,Hr as b2Joint_WakeBodies,de as b2LeftPerp,Yt as b2Length,pe as b2LengthSquared,$t as b2Lerp,Fo as b2MakeBox,Ir as b2MakeOffsetBox,gs as b2MakeOffsetPolygon,sn as b2MakePolygon,vt as b2MakeProxy,Di as b2MakeRot,Wa as b2MakeRoundedBox,xr as b2MakeSquare,To as b2Manifold,je as b2MassData,Mi as b2Max,M2 as b2MaxFloat,k2 as b2MaxInt,Ji as b2Min,J2 as b2MinFloat,P2 as b2MinInt,$o as b2MotorJointDef,bb as b2MotorJoint_GetAngularOffset,fb as b2MotorJoint_GetCorrectionFactor,lb as b2MotorJoint_GetLinearOffset,ub as b2MotorJoint_GetMaxForce,mb as b2MotorJoint_GetMaxTorque,db as b2MotorJoint_SetAngularOffset,yb as b2MotorJoint_SetCorrectionFactor,cb as b2MotorJoint_SetLinearOffset,pb as b2MotorJoint_SetMaxForce,hb as b2MotorJoint_SetMaxTorque,Qo as b2MouseJointDef,Db as b2MouseJoint_GetMaxForce,Jb as b2MouseJoint_GetSpringDampingRatio,wb as b2MouseJoint_GetSpringHertz,Ab as b2MouseJoint_GetTarget,Mb as b2MouseJoint_SetMaxForce,vb as b2MouseJoint_SetSpringDampingRatio,Cb as b2MouseJoint_SetSpringHertz,Bb as b2MouseJoint_SetTarget,R2 as b2Mul,$ as b2MulAdd,ns as b2MulMV,Pa as b2MulRot,it as b2MulSV,yt as b2MulSub,z2 as b2MulTransforms,Pi as b2NLerp,Ht as b2Neg,lt as b2Normalize,H2 as b2NormalizeChecked,sr as b2NormalizeRot,gr as b2PointInCapsule,_r as b2PointInCircle,Br as b2PointInPolygon,ge as b2Polygon,Zo as b2PrismaticJointDef,Kl as b2PrismaticJoint_EnableLimit,td as b2PrismaticJoint_EnableMotor,Yl as b2PrismaticJoint_EnableSpring,$l as b2PrismaticJoint_GetLowerLimit,id as b2PrismaticJoint_GetMaxMotorForce,sd as b2PrismaticJoint_GetMotorForce,nd as b2PrismaticJoint_GetMotorSpeed,zl as b2PrismaticJoint_GetSpringDampingRatio,Ol as b2PrismaticJoint_GetSpringHertz,Ql as b2PrismaticJoint_GetUpperLimit,Hl as b2PrismaticJoint_IsLimitEnabled,ed as b2PrismaticJoint_IsMotorEnabled,Nl as b2PrismaticJoint_IsSpringEnabled,Zl as b2PrismaticJoint_SetLimits,rd as b2PrismaticJoint_SetMaxMotorForce,od as b2PrismaticJoint_SetMotorSpeed,Ul as b2PrismaticJoint_SetSpringDampingRatio,Wl as b2PrismaticJoint_SetSpringHertz,ms as b2QueryFilter,ws as b2RayCastCapsule,He as b2RayCastCircle,Po as b2RayCastInput,vs as b2RayCastPolygon,rn as b2RayCastSegment,ys as b2RayResult,oe as b2RelativeAngle,mo as b2RevoluteJointDef,Sd as b2RevoluteJoint_EnableLimit,Cd as b2RevoluteJoint_EnableMotor,ud as b2RevoluteJoint_EnableSpring,Id as b2RevoluteJoint_GetAngle,gd as b2RevoluteJoint_GetLowerLimit,Pd as b2RevoluteJoint_GetMaxMotorTorque,Jd as b2RevoluteJoint_GetMotorSpeed,Md as b2RevoluteJoint_GetMotorTorque,xd as b2RevoluteJoint_GetSpringDampingRatio,yd as b2RevoluteJoint_GetSpringHertz,Bd as b2RevoluteJoint_GetUpperLimit,_d as b2RevoluteJoint_IsLimitEnabled,wd as b2RevoluteJoint_IsMotorEnabled,hd as b2RevoluteJoint_IsSpringEnabled,Ad as b2RevoluteJoint_SetLimits,Dd as b2RevoluteJoint_SetMaxMotorTorque,vd as b2RevoluteJoint_SetMotorSpeed,fd as b2RevoluteJoint_SetSpringDampingRatio,md as b2RevoluteJoint_SetSpringHertz,be as b2RightPerp,rt as b2Rot,q2 as b2Rot_GetAngle,V2 as b2Rot_GetXAxis,Y2 as b2Rot_GetYAxis,K2 as b2Rot_IsValid,K as b2RotateVector,Oe as b2Segment,hr as b2SegmentDistance,is as b2SegmentDistanceResult,Gn as b2SensorEvents,eh as b2SetAllocator,Ra as b2SetAssertFcn,Ta as b2SetLengthUnitsPerMeter,jo as b2ShapeCast,Cr as b2ShapeCastCapsule,Ar as b2ShapeCastCircle,Ko as b2ShapeCastInput,lo as b2ShapeCastPairInput,wr as b2ShapeCastPolygon,Js as b2ShapeCastSegment,us as b2ShapeDef,Be as b2ShapeDistance,St as b2ShapeId,Y as b2ShapeType,Ic as b2Shape_AreContactEventsEnabled,Bc as b2Shape_AreHitEventsEnabled,_c as b2Shape_ArePreSolveEventsEnabled,fc as b2Shape_AreSensorEventsEnabled,xc as b2Shape_EnableContactEvents,gc as b2Shape_EnableHitEvents,Sc as b2Shape_EnablePreSolveEvents,yc as b2Shape_EnableSensorEvents,Fc as b2Shape_GetAABB,oc as b2Shape_GetBody,Jc as b2Shape_GetCapsule,vc as b2Shape_GetChainSegment,Cc as b2Shape_GetCircle,Xc as b2Shape_GetClosestPoint,Ec as b2Shape_GetContactCapacity,jc as b2Shape_GetContactData,lc as b2Shape_GetDensity,hc as b2Shape_GetFilter,bc as b2Shape_GetFriction,Gc as b2Shape_GetParentChain,Mc as b2Shape_GetPolygon,uc as b2Shape_GetRestitution,wc as b2Shape_GetSegment,Ac as b2Shape_GetType,sc as b2Shape_GetUserData,rc as b2Shape_IsSensor,zu as b2Shape_IsValid,ac as b2Shape_RayCast,Pc as b2Shape_SetCapsule,Dc as b2Shape_SetCircle,cc as b2Shape_SetDensity,mc as b2Shape_SetFilter,dc as b2Shape_SetFriction,Tc as b2Shape_SetPolygon,pc as b2Shape_SetRestitution,kc as b2Shape_SetSegment,nc as b2Shape_SetUserData,ic as b2Shape_TestPoint,Mn as b2Simplex,ah as b2SleepMilliseconds,zo as b2Solve22,J as b2Sub,bo as b2Sweep,cs as b2TOIInput,ls as b2TOIOutput,_s as b2TimeOfImpact,at as b2Transform,H as b2TransformPoint,Oa as b2TransformPolygon,vo as b2UnwindAngle,mr as b2ValidateHull,g as b2Vec2,rr as b2Vec2_IsValid,tn as b2WeldJointDef,Yb as b2WeldJoint_GetAngularDampingRatio,qb as b2WeldJoint_GetAngularHertz,Fb as b2WeldJoint_GetLinearDampingRatio,Eb as b2WeldJoint_GetLinearHertz,Vb as b2WeldJoint_SetAngularDampingRatio,Xb as b2WeldJoint_SetAngularHertz,jb as b2WeldJoint_SetLinearDampingRatio,Lb as b2WeldJoint_SetLinearHertz,en as b2WheelJointDef,Nd as b2WheelJoint_EnableLimit,Kd as b2WheelJoint_EnableMotor,jd as b2WheelJoint_EnableSpring,Od as b2WheelJoint_GetLowerLimit,eb as b2WheelJoint_GetMaxMotorTorque,Qd as b2WheelJoint_GetMotorSpeed,Zd as b2WheelJoint_GetMotorTorque,Yd as b2WheelJoint_GetSpringDampingRatio,qd as b2WheelJoint_GetSpringHertz,Ud as b2WheelJoint_GetUpperLimit,Wd as b2WheelJoint_IsLimitEnabled,Hd as b2WheelJoint_IsMotorEnabled,Fd as b2WheelJoint_IsSpringEnabled,zd as b2WheelJoint_SetLimits,tb as b2WheelJoint_SetMaxMotorTorque,$d as b2WheelJoint_SetMotorSpeed,Vd as b2WheelJoint_SetSpringDampingRatio,Xd as b2WheelJoint_SetSpringHertz,bs as b2WorldDef,co as b2WorldId,p2 as b2World_CastCapsule,b2 as b2World_CastCircle,u2 as b2World_CastPolygon,c2 as b2World_CastRay,l2 as b2World_CastRayClosest,Vu as b2World_Draw,qh as b2World_DumpMemoryStats,Zu as b2World_EnableContinuous,$u as b2World_EnableSleeping,Qu as b2World_EnableWarmStarting,x2 as b2World_Explode,Yu as b2World_GetBodyEvents,Wu as b2World_GetContactEvents,Xh as b2World_GetCounters,f2 as b2World_GetGravity,Fh as b2World_GetProfile,Nu as b2World_GetSensorEvents,Ou as b2World_IsValid,n2 as b2World_OverlapAABB,i2 as b2World_OverlapCapsule,r2 as b2World_OverlapCircle,a2 as b2World_OverlapPolygon,o2 as b2World_SetContactTuning,m2 as b2World_SetCustomFilterCallback,y2 as b2World_SetGravity,e2 as b2World_SetHitEventThreshold,h2 as b2World_SetPreSolveCallback,t2 as b2World_SetRestitutionThreshold,Bi as b2World_Step,ch as b2Yield,Nh as mpx,Wh as pxm,or as pxmVec2}; From a4bcda08e12d0721bfe709a4e95f036ee0f28d64 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:21:43 -0800 Subject: [PATCH 12/14] CreatePolygonFromVertices: fix function comment for return type --- src/physics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics.js b/src/physics.js index 2c5096a..fac5713 100644 --- a/src/physics.js +++ b/src/physics.js @@ -993,7 +993,7 @@ export function CreatePolygonFromEarcut (data) /** * Creates a polygon from Vertex and Index data and attaches it to a body. * @param {PolygonVertexConfig} data - Configuration for the polygon. - * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object. + * @returns {b2BodyId} The created polygon's body ID. * @memberof Physics */ export function CreatePolygonFromVertices (data) From 01346bf8c95fd1c28597c821e1f3d3fdbc482553 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:29:43 -0800 Subject: [PATCH 13/14] revert incorrect function comment --- src/physics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics.js b/src/physics.js index fac5713..2c5096a 100644 --- a/src/physics.js +++ b/src/physics.js @@ -993,7 +993,7 @@ export function CreatePolygonFromEarcut (data) /** * Creates a polygon from Vertex and Index data and attaches it to a body. * @param {PolygonVertexConfig} data - Configuration for the polygon. - * @returns {b2BodyId} The created polygon's body ID. + * @returns {{bodyId: b2BodyId, shapeId: b2ShapeId, object: b2Polygon}} The created polygon's body ID, shape ID, and object. * @memberof Physics */ export function CreatePolygonFromVertices (data) From b6b8daa453b5f7853c2ef27c3fa2ff87ca9f484f Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 18 Jan 2025 09:30:07 -0800 Subject: [PATCH 14/14] update dist --- dist/PhaserBox2D-Debug.js | 2 +- dist/PhaserBox2D-Render.js | 2 +- dist/PhaserBox2D.js | 2 +- dist/PhaserBox2D.min.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/PhaserBox2D-Debug.js b/dist/PhaserBox2D-Debug.js index 5e10632..f3fd2c9 100644 --- a/dist/PhaserBox2D-Debug.js +++ b/dist/PhaserBox2D-Debug.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Saturday, 18 January 2025 at 09:17 + * Saturday, 18 January 2025 at 09:29 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D-Render.js b/dist/PhaserBox2D-Render.js index ba47f35..d9f7cea 100644 --- a/dist/PhaserBox2D-Render.js +++ b/dist/PhaserBox2D-Render.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Saturday, 18 January 2025 at 09:17 + * Saturday, 18 January 2025 at 09:29 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D.js b/dist/PhaserBox2D.js index 87e3c6d..73c380e 100644 --- a/dist/PhaserBox2D.js +++ b/dist/PhaserBox2D.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Saturday, 18 January 2025 at 09:17 + * Saturday, 18 January 2025 at 09:29 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is diff --git a/dist/PhaserBox2D.min.js b/dist/PhaserBox2D.min.js index c43be6d..a5a53c2 100644 --- a/dist/PhaserBox2D.min.js +++ b/dist/PhaserBox2D.min.js @@ -1,7 +1,7 @@ /** * @license * Phaser Box2D v1.1.0 - * Saturday, 18 January 2025 at 09:17 + * Saturday, 18 January 2025 at 09:29 * * This library includes code that is ported from the original C version. The original C code is Copyright 2023 Erin Catto * and was released under the MIT license. The JavaScript port of the C code along with all additional code is